1
0
mirror of https://codeberg.org/tenplus1/mobs_redo.git synced 2025-07-20 17:20:23 +02:00

Compare commits

..

130 Commits

Author SHA1 Message Date
84377ee259 fix on_pick_up example in api.txt 2025-06-14 08:51:26 +01:00
5077217497 in peaceful mode dont register monster abm's 2025-06-03 13:41:39 +01:00
bae9cb12e2 add missing log level (thx Niklp) 2025-05-30 07:45:47 +01:00
126e5afc24 default active_block_range to 4 if not set 2025-05-26 07:23:15 +01:00
112c512c6e add mob repellent info 2025-05-25 13:32:46 +01:00
0f5b0e382d add recipe for mob repellent 2025-05-23 12:45:56 +01:00
5ed3a34cf3 remove self.attack_players check from do_punch 2025-05-20 08:13:06 +01:00
f44441c580 remove tester 2025-05-17 07:44:15 +01:00
2cf43ffc4e fix fear_height defaults 2025-05-17 07:43:26 +01:00
0d6b794fa0 default fear_height to 2 2025-05-16 10:46:45 +01:00
42da759407 tamed npc/animal wont attack players unless provoked 2025-05-15 15:44:22 +01:00
c0c4c3ea48 tweak general_attack 2025-05-15 14:34:38 +01:00
f5817061ce little tidy 2025-05-11 11:01:32 +01:00
43ad058efa change minetest. to core. 2025-05-04 12:25:59 +01:00
b977431e21 is_node_dangerous only if damage > 0 2025-05-01 08:01:12 +01:00
68b25c9d08 use tnt or mcl_explosions for mobs:boom 2025-04-11 10:12:30 +01:00
24adcae920 add self check in tnt boom 2025-04-11 08:46:01 +01:00
16a04547ab fix texture name 2025-04-10 09:42:58 +01:00
3a7b1bbfe6 added mobs_heart_particle.png 2025-04-09 15:15:41 +01:00
01a60d9a55 add particles to replace defaults 2025-04-09 15:11:47 +01:00
99f4fc1768 move deprecated functions from api to compatibility.lua 2025-04-08 08:33:25 +01:00
027620bfa3 tidy comments, change float var 2025-04-05 12:09:03 +01:00
854834f04e deprecate self.jump and add mobs.compatibility_check function. 2025-04-04 10:12:46 +01:00
5fb7b91db0 fix typo 2025-03-20 08:06:40 +00:00
badb889cf3 add 'mob_infotext' setting 2025-03-20 08:05:24 +00:00
ca7aeec95a add nil check on_punch 2025-03-18 08:06:40 +00:00
14f391bf2c add ukrainian translation (thx Fromkaniv) 2025-03-15 16:37:52 +00:00
0bf3915315 return func 2025-03-12 08:16:26 +00:00
b81c2aeab6 update dates, add sound_play check 2025-03-12 08:03:17 +00:00
0a62f05132 add mob repellent 2025-02-09 12:12:52 +00:00
9f472fb690 tweak do_jump 2025-02-04 15:06:59 +00:00
c62b013825 add pick_up and on_pick_up features. 2025-02-04 10:21:10 +00:00
4b825b3e86 call do_punch after damage calculated 2025-02-01 13:57:27 +00:00
f09b6d1730 pass mesh to arrow (thx kiedtl) 2025-01-20 08:00:26 +00:00
a3ede86365 update api.txt 2025-01-19 08:15:33 +00:00
4b556a4d16 pass damage to do_punch 2025-01-18 08:17:11 +00:00
01e015dc0f disable is_mob flag, something fishy with mineclonia 2025-01-17 08:08:24 +00:00
d7998a9ea7 abort on_step when mob expires (thx tour-ist) 2025-01-09 16:20:23 +00:00
57fe6cf2e3 tweak & tidy code, exploding mobs brighten and glow 2024-12-28 11:19:44 +00:00
b170b51f2d tweak do_jump so mobs dont jump on carpets 2024-12-26 11:08:36 +00:00
dca4159fc4 code tidy 2024-12-26 08:48:35 +00:00
219d477c2a wee tidy 2024-12-20 10:49:52 +00:00
c8e91d1958 tweak spawning 2024-12-19 07:36:23 +00:00
22d7ea79fd fix riding gravity 2024-12-13 15:49:52 +00:00
c24874a3bf fix map_load chance check 2024-12-08 10:33:54 +00:00
c25975e7ea fix typo 2024-12-02 06:34:28 +00:00
03ce8ada6b tweak/tidy, check env damage when riding mob 2024-12-01 12:18:44 +00:00
cc60499637 tweak n tidy 2024-11-30 12:35:22 +00:00
58792311c7 add immune_to check to is_node_dangerous function 2024-11-28 13:07:53 +00:00
527fe8c2d5 add nodes to immune_to ability. 2024-11-27 08:22:09 +00:00
6a7c221ce1 fix boom texture 2024-11-22 14:13:22 +00:00
b8052c817c replace empty var 2024-11-22 14:08:34 +00:00
e17ea86bf5 restore mobs:boom order 2024-11-22 08:11:25 +00:00
ca76558edd switch node/entity setting in mobs:boom 2024-11-21 15:35:07 +00:00
bde53c3475 add mobs:is_invisible() function, update api.txt 2024-11-16 08:16:55 +00:00
2e4664a5ce use invisibility mod api 2024-11-14 08:17:41 +00:00
39f9f8df31 add reach option to replace function. 2024-11-13 11:04:27 +00:00
1b1f681886 tidy spawning 2024-11-10 11:41:32 +00:00
627d468b9a add replace sound, tweak spawn egg y_pos 2024-10-28 13:27:39 +00:00
e9c3d6c505 add brazilian translation (thx pixelzone) 2024-10-26 10:21:27 +01:00
1f8ca901b5 fix russian typo 2024-10-23 08:02:34 +01:00
816461286b update russian translation (thx SkyBuilder1717) 2024-10-22 17:00:17 +01:00
430af1e91d add 'mobs_disable_damage_kb' setting 2024-10-20 09:19:52 +01:00
79fb4f7ead disable follow_stop 2024-10-19 15:06:59 +01:00
f746f4b1e0 fix knockback when breeding 2024-10-12 10:27:25 +01:00
e59fd53ee9 make sure def.gain has a value 2024-10-11 10:24:07 +01:00
faf511ff8c fix visharm indicate on active 2024-10-10 11:30:22 +01:00
a35afc8299 disable node hearing by default 2024-10-10 10:37:47 +01:00
219db764bf forgot def.loudness check 2024-10-02 15:51:05 +01:00
e4a5ead82c pass def onto hearing nodes 2024-10-02 15:13:37 +01:00
f4861ced2a add on_sound node support and example. 2024-10-02 14:57:07 +01:00
1dd81eb008 tweak mob hear function 2024-10-01 09:08:52 +01:00
64c6085f09 wee jump bug 2024-09-17 09:43:01 +01:00
e8e774566b tweak collision, falling and arrow drops. 2024-09-14 12:25:52 +01:00
e55bf4d951 mob hear nil check for player 2024-09-14 07:51:06 +01:00
f1b5a66049 lil tweak 2024-09-08 15:55:26 +01:00
26215cd221 add min_y and max_y to spawning abm/lbm's 2024-08-23 17:37:51 +01:00
29314186b3 tweak damage 2024-08-23 15:07:08 +01:00
dce2abfcfe add missing glass sounds 2024-08-11 08:41:25 +01:00
e561864e82 udpate api.txt 2024-08-11 08:17:02 +01:00
59c19fca98 update german translation 2024-08-10 17:39:01 +01:00
a8297e6a8e tidy and tweak code, implement sound check for mineclon* 2024-08-10 13:18:57 +01:00
bc6b8931da tidy code 2024-08-09 14:46:28 +01:00
3e24677649 Add basic mineclonia enchantments (sharpness, fire_aspect, knockback) 2024-08-09 09:15:06 +01:00
57d6859b93 tweak loudness calculation for mod hearing 2024-08-04 08:25:48 +01:00
1f6867bf25 alternative to using on_punch for hearing ability, remove food xp desc 2024-08-03 23:47:21 +01:00
b1da38456d quick value change for mob listening 2024-08-03 16:59:44 +01:00
341f92f118 harden sound_play checks 2024-08-03 11:56:52 +01:00
c3d74394a7 update readme 2024-08-03 11:43:14 +01:00
964451fd78 add mob hearing feature and self.on_sound() function 2024-08-03 11:35:28 +01:00
ef9f492bad update {eatable} function 2024-07-27 18:28:44 +01:00
79c85e0551 code tidy 2024-07-27 08:33:22 +01:00
cc14704651 add helper function for {eatable} 2024-07-26 17:00:58 +01:00
8115f61ac9 add {eatable} group to food items and update infotext 2024-07-26 14:42:34 +01:00
77b53b9054 fix timer bug 2024-07-16 07:21:50 +01:00
fc7269cc8c remove fallback node from inventory and update version 2024-07-01 09:28:05 +01:00
fb2a247d31 change fall_damage check to use true/false 2024-07-01 07:49:03 +01:00
03fbe477c3 shrink fallback node image 2024-06-29 08:25:15 +01:00
91be60be9b add fallback node for when [game] doesn't have dirt alias defined 2024-06-29 08:22:33 +01:00
e11f383589 harden mob limit check 2024-06-20 07:58:04 +01:00
313382dcaa increase go_to time to 20 and add force flag to do_attack 2024-05-25 07:50:16 +01:00
1536b9a5fc add mob_class:go_to(pos) function 2024-05-24 17:28:35 +01:00
be2d630fdf add ":" to beginning of egg registration to help with mobs registered outwith mod name 2024-05-05 07:55:49 +01:00
99bea53af3 make on_death compatible (return either player or nil) 2024-04-26 11:07:08 +01:00
d20dfa0b41 added check for on_death() function before api's own on_die() 2024-04-26 07:44:39 +01:00
e9180febc6 fix baby mob textures when grown 2024-04-25 08:29:48 +01:00
c4561a2207 mount.lua nil check 2024-04-16 10:41:01 +01:00
998637fc3d added infotext and mob follows improvements (thx Kazooo) 2024-04-08 08:37:59 +01:00
de0914312c stop swimming mobs going above water surface 2024-04-02 09:16:59 +01:00
5a6ec7080f attacking mobs should stay inside their own medium 2024-04-01 14:54:55 +01:00
129b24b159 add entity name in infotext 2024-03-12 11:13:16 +00:00
35cc60c355 tweak saddle recipe, fix spawner error 2024-03-08 15:04:58 +00:00
903b1e34df fix default self.state 2024-03-03 17:30:22 +00:00
87d13c857f replace :distance with get_distance() function 2024-03-03 17:09:30 +00:00
17dafff8ef add attack_ignore feature (thx ShadowOfHassen for idea) 2024-03-01 16:01:18 +00:00
95f3e98867 set is_ground_content for spawner and meat blocks (thx SwissAlpS) 2024-02-27 08:05:02 +00:00
b3b89e6dea fix spawner chance 2024-02-23 17:12:14 +00:00
822e78fd32 tweak player detection (thx whosit) 2024-02-23 17:09:42 +00:00
dd9b3d7add if punch_attack_uses is 0 then dont add wear to tool 2024-02-20 07:47:37 +00:00
d4a25064ea use alternative to colorspec_to_bytes 2024-02-01 08:34:46 +00:00
70118fc8da only update object props when changes (thx whosit) 2024-01-31 09:59:31 +00:00
7c7a7345af change nametag texture and description to stand out from mineclone version 2024-01-30 08:02:17 +00:00
ceefbcec39 add some missing mineclone groups 2024-01-29 16:01:59 +00:00
97771f8e65 add self.node_damage flag (true by default) 2024-01-26 13:05:43 +00:00
1cacb02a6a add missing formspec escape 2024-01-21 09:34:45 +00:00
47e91b9b6b add pint sized rune to shrink tamed animals 2024-01-12 10:44:39 +00:00
a6a3b44c96 ability to override initial_properties when using minetest.add_entity() 2023-12-29 08:41:45 +00:00
be7b6bc5fe can now add 'nametag = "mob name"' in mob definition 2023-12-05 08:23:04 +00:00
68076c7626 add back arrows physical setting 2023-12-02 07:47:13 +00:00
099d15d810 mob arrows now use raycasting to be more accurate 2023-11-29 12:11:45 +00:00
26 changed files with 2200 additions and 2277 deletions

3188
api.lua

File diff suppressed because it is too large Load Diff

252
api.txt
View File

@ -50,7 +50,7 @@ functions needed for the mob to work properly which contains the following:
set to 0 for jumping mobs only. set to 0 for jumping mobs only.
'randomly_turn' if set to false then mob will not turn to face player or 'randomly_turn' if set to false then mob will not turn to face player or
randomly turn while walking or standing. randomly turn while walking or standing.
'jump' when true allows your mob to jump updwards. 'jump' when true allows your mob to jump updwards[DEPRECATED].
'jump_height' holds the height your mob can jump, 0 to disable jumping. 'jump_height' holds the height your mob can jump, 0 to disable jumping.
'can_leap' when true obstacles like fences or pits wont stop a mob 'can_leap' when true obstacles like fences or pits wont stop a mob
from trying to jump out. from trying to jump out.
@ -83,8 +83,8 @@ functions needed for the mob to work properly which contains the following:
'lava_damage' holds the damage per second inflicted to mobs when standing 'lava_damage' holds the damage per second inflicted to mobs when standing
in lava. in lava.
'fire_damage' holds the damage per second inflicted to mobs when standing 'fire_damage' holds the damage per second inflicted to mobs when standing
in fire. 'node_damage' True by default, will harm mobs when inside damage_per_second
nodes.
'light_damage' holds the damage per second inflicted to mobs when light 'light_damage' holds the damage per second inflicted to mobs when light
level is between the min and max values below level is between the min and max values below
'light_damage_min' minimum light value when mob is affected (default: 14) 'light_damage_min' minimum light value when mob is affected (default: 14)
@ -92,7 +92,7 @@ functions needed for the mob to work properly which contains the following:
When set to 16 then only natural light will kill mob. When set to 16 then only natural light will kill mob.
'suffocation' when > 0 mobs will suffocate inside solid blocks and will be 'suffocation' when > 0 mobs will suffocate inside solid blocks and will be
hurt by the value given every second (0 to disable). hurt by the value given every second (0 to disable).
'floats' when set to 1 mob will float in water, 0 has them sink. 'floats' when True mob will float in water, otherwise they sink.
'follow' mobs follow player when holding any of the items which appear '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 on this table, the same items can be fed to a mob to tame or
breed e.g. {"farming:wheat", "default:apple", "group:fish"} breed e.g. {"farming:wheat", "default:apple", "group:fish"}
@ -102,13 +102,15 @@ functions needed for the mob to work properly which contains the following:
'docile_by_day' when true has mobs wandering around during daylight 'docile_by_day' when true has mobs wandering around during daylight
hours and only attacking player at night or when hours and only attacking player at night or when
provoked. provoked.
'attack_chance' 0 to 100 chance the mob will attack (default is 5). 'attack_chance' 0 to 100 chance the mob will attack (default is 5),
set to 100 so that mob needs to be provoked to attack.
'attack_patience' Time in seconds before mob gives up attacking if 'attack_patience' Time in seconds before mob gives up attacking if
player isn't seen (Defaults to 11). player isn't seen (Defaults to 11).
'attack_monsters' when true mob will attack monsters. 'attack_monsters' when true mob will attack monsters.
'attack_animals' when true mob will attack animals. 'attack_animals' when true mob will attack animals.
'attack_npcs' when true mob will attack npcs within range. 'attack_npcs' when true mob will attack npcs within range.
'attack_players' when true mob will attack players nearby. 'attack_players' when true mob will attack players nearby.
'attack_ignore' string or table of mob names not to attack.
'owner_loyal' when true non-docile tamed mobs attack anything player 'owner_loyal' when true non-docile tamed mobs attack anything player
punches when nearby. punches when nearby.
'group_attack' when true has same mob type grouping together to attack 'group_attack' when true has same mob type grouping together to attack
@ -175,6 +177,9 @@ functions needed for the mob to work properly which contains the following:
{"default:gold_lump", -10} -- heals by 10 health points. {"default:gold_lump", -10} -- heals by 10 health points.
{"default:coal_block", 20} -- 20 damage when hit on head with coal blocks. {"default:coal_block", 20} -- 20 damage when hit on head with coal blocks.
{"all"} -- stops all weapons causing damage apart from those on list. {"all"} -- stops all weapons causing damage apart from those on list.
nodes can also be added so that node_per_second damage
does not affect the mob either e.g.
{"ethereal:crystal_spike", 0} -- causes no damage.
'makes_footstep_sound' when true you can hear mobs walking. 'makes_footstep_sound' when true you can hear mobs walking.
'sounds' this is a table with sounds of the mob 'sounds' this is a table with sounds of the mob
@ -226,8 +231,6 @@ functions needed for the mob to work properly which contains the following:
'rotate' custom model rotation, 0 = front, 90 = side, 180 = back, 'rotate' custom model rotation, 0 = front, 90 = side, 180 = back,
270 = other side. 270 = other side.
'glow' has mob glow without light source, 0 to 15 or nil to disable 'glow' has mob glow without light source, 0 to 15 or nil to disable
'double_melee_attack' when true has the api choose between 'punch' and
'punch2' animations. [DEPRECATED]
'animation' holds a table containing animation names and settings for use with 'animation' holds a table containing animation names and settings for use with
mesh models: mesh models:
@ -286,11 +289,12 @@ eating.
y offset by using this instead: y offset by using this instead:
{ {
{"group:grass", "air", 0}, {"group:grass", "air", 0},
{"default:dirt_with_grass", "default:dirt", -1} {"default:dirt_with_grass", "default:dirt", -1, 0}
} }
'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg" 'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg"
'replace_rate' how random should the replace rate be (typically 10) 'replace_rate' how random should the replace rate be (typically 10)
'replace_offset' +/- value to check specific node to replace 'replace_offset' +/- y offset value to check specific node to replace
'reach' horizontal reach around mob for replace, default is 0
'on_replace(self, pos, oldnode, newnode)' is called when mob is about to 'on_replace(self, pos, oldnode, newnode)' is called when mob is about to
replace a node. replace a node.
@ -305,6 +309,25 @@ eating.
properties. (DEPRECATED, use on_replace to make changes). properties. (DEPRECATED, use on_replace to make changes).
Pickup Items
------------
'pick_up' table of itemstrings the mob will pick up.
'on_pick_up' function that will be called on item pickup - arguments are
(self, itemtable) and can return nil or a a modified itemstack e.g.
on_pick_up = function(self, itemtable)
local istack = ItemStack(itemtable.itemstring)
print("-- took", istack:get_name())
istack:take_item()
return istack
end,
Custom Definition Functions Custom Definition Functions
--------------------------- ---------------------------
@ -326,13 +349,16 @@ enhance mob functionality and have them do many interesting things:
'on_grown' is called when a child mob has grown up, only paramater is 'on_grown' is called when a child mob has grown up, only paramater is
(self). (self).
'do_punch' called when mob is punched with paramaters (self, hitter, 'do_punch' called when mob is punched with paramaters (self, hitter,
time_from_last_punch, tool_capabilities, direction), return time_from_last_punch, tool_capabilities, direction, damage),
false to stop punch damage and knockback from taking place. return false to stop punch damage and knockback from taking
place.
'custom_attack' when set this function is called instead of the normal mob 'custom_attack' when set this function is called instead of the normal mob
melee attack, parameters are (self, to_attack) and if true melee attack, parameters are (self, to_attack) and if true
is returned normal attack function continued. is returned normal attack function continued.
'on_die' a function that is called when mob is killed (self, pos), also 'on_die' a function that is called when mob is killed (self, pos), also
has access to self.cause_of_death table. has access to self.cause_of_death table.
'on_death' Official engine version of above when mob killed (self, killer),
'killer' is only returned if player killed the mob.
'on_flop' function called when flying or swimmimng mob is no longer in 'on_flop' function called when flying or swimmimng mob is no longer in
air/water, (self) paramater and return true to skip the built air/water, (self) paramater and return true to skip the built
in api flop feature. in api flop feature.
@ -340,6 +366,24 @@ enhance mob functionality and have them do many interesting things:
active and which has access to all of the self.* variables active and which has access to all of the self.* variables
e.g. (self.health for health or self.standing_in for node e.g. (self.health for health or self.standing_in for node
status), return with 'false' to skip remainder of mob API. status), return with 'false' to skip remainder of mob API.
'on_sound' (self, def) called when mob is inside the hearing distance of
a sound, passes a def table containing:
'sound' the sound being played,
'pos' position the sound originated (only sounds with pos detected),
'gain' original gain of sound,
'distance' distance of mob from sound source,
'loudness' how loud sound is to mob (percentage of gain heard at distance)
'player' player name sound originated, [NOT IN USE]
'object' object reference sound originated, [NOT IN USE]
'max_hear_distance' max distance sound can be heard from source.
Hearing Nodes
-------------
If a node has the {on_sound = 1} group and an on_sound() function set as above then
nodes within 8 blocks of a sound will be activated and the function run. Check the
"mobs:hearing_vines" node as an example which has mesecons support when active.
Internal Variables Internal Variables
@ -397,7 +441,8 @@ Each mob contains a set of functions that can be called for use internally or fr
another mod entirely, replace mob_class with the mob entity variable: another mod entirely, replace mob_class with the mob entity variable:
mob_class:mob_sound(sound) -- play sound at mob position mob_class:mob_sound(sound) -- play sound at mob position
mob_class:do_attack(player) -- if not already attacking, attack object given mob_class:do_attack(player [, force]) -- if not already attacking, attack object given,
forced being true stops attacking current target and focuses on one given
mob_class:stop_attack() -- stops mob attacking mob_class:stop_attack() -- stops mob attacking
mob_class:collision() -- checks for player collision with mob and returns {x, z} vector mob_class:collision() -- checks for player collision with mob and returns {x, z} vector
mob_class:set_velocity(velocity) -- move at velocity in the facing direction mob_class:set_velocity(velocity) -- move at velocity in the facing direction
@ -414,7 +459,9 @@ mob_class:day_docile() -- return True if mob docile during current daytime
mob_class:mob_expire(pos, dtime) -- check if mob is to despawn mob_class:mob_expire(pos, dtime) -- check if mob is to despawn
mob_class:get_nodes() -- get specific nodes around mob mob_class:get_nodes() -- get specific nodes around mob
mob_class:on_blast(damage) -- function called when mob in blast area mob_class:on_blast(damage) -- function called when mob in blast area
mob_class:is_inside(itemtable) -- returns True is mob collisionbox inside any node/group in table mob_class:is_inside(itemtable) -- returns True is mob collisionbox inside any node/group
in table
mob_class:go_to(pos) -- makes mob go to that position or nearby
Adding Mobs in World Adding Mobs in World
@ -538,11 +585,13 @@ This function registers a arrow for mobs with the attack type shoot.
'definition' is a table with the following values: 'definition' is a table with the following values:
'visual' same is in minetest.register_entity() 'visual' same is in minetest.register_entity()
'visual_size' same is in minetest.register_entity() 'visual_size' same is in minetest.register_entity()
'mesh' same is in minetest.register_entity()
'textures' 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 'collide_with_objects' same as above
'velocity' the velocity of the arrow 'velocity' the velocity of the arrow
'drop' if set to true any arrows hitting a node will drop as item 'drop' if set to true any arrows hitting a node will drop as item,
if number given then chance (1/num) of item dropping will
be used. arrow "mymob:myarrow" will use item of same name.
'hit_player' a function that is called when the arrow hits a player; 'hit_player' a function that is called when the arrow hits a player;
this function should hurt the player, the parameters are this function should hurt the player, the parameters are
(self, player) (self, player)
@ -562,7 +611,7 @@ This function registers a arrow for mobs with the attack type shoot.
0 for no glow) 0 for no glow)
'rotate' integer value in degrees to rotate arrow 'rotate' integer value in degrees to rotate arrow
'on_step' is a custom function when arrow is active, nil for 'on_step' is a custom function when arrow is active, nil for
default. default. (self, dtime, moveresult)
'on_punch' is a custom function when arrow is punched, nil by default 'on_punch' is a custom function when arrow is punched, nil by default
'collisionbox' is hitbox table for arrow, {-.1,-.1,-.1,.1,.1,.1} by default. 'collisionbox' is hitbox table for arrow, {-.1,-.1,-.1,.1,.1,.1} by default.
'lifetime' contains float value for how many seconds arrow exists in 'lifetime' contains float value for how many seconds arrow exists in
@ -591,11 +640,11 @@ Explosion Function
mobs:explosion(pos, radius) -- DEPRECATED!!! use mobs:boom() instead mobs:explosion(pos, radius) -- DEPRECATED!!! use mobs:boom() instead
mobs:boom(self, pos, radius, damage_radius, texture) mobs:boom(self, pos, damage_radius, entity_radius, texture)
'self' mob entity 'self' mob entity
'pos' centre position of explosion 'pos' centre position of explosion
'radius' radius of explosion (typically set to 3) 'damage_radius' radius of node damage (typically 3)
'damage_radius' radius of damage around explosion 'entity_radius' radius of explosion to players and mobs
'texture' particle texture during explosion, defaults to "tnt_smoke.png" 'texture' particle texture during explosion, defaults to "tnt_smoke.png"
This function generates an explosion which removes nodes in a specific radius This function generates an explosion which removes nodes in a specific radius
@ -812,6 +861,7 @@ External Settings for "minetest.conf"
'mobs_drop_items' when false mobs no longer drop items when they die. 'mobs_drop_items' when false mobs no longer drop items when they die.
'mobs_griefing' when false mobs cannot break blocks when using either 'mobs_griefing' when false mobs cannot break blocks when using either
pathfinding level 2, replace functions or mobs:boom pathfinding level 2, replace functions or mobs:boom
'mobs_can_hear' True by default, allows mobs to hear sound around them.
function. function.
'mob_nospawn_range' Minimum range a mob can spawn near player (def: 12) '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_active_limit' Number of active mobs in game, 0 for unlimited
@ -819,10 +869,9 @@ External Settings for "minetest.conf"
mob for obstructions before spawning, otherwise it mob for obstructions before spawning, otherwise it
defaults to checking the height of the mob only. defaults to checking the height of the mob only.
'mob_smooth_rotate' Enables smooth rotation when mobs turn by default. 'mob_smooth_rotate' Enables smooth rotation when mobs turn by default.
'mob_height_fix' Enabled by default, increases smaller mob heights so they wont 'mob_height_fix' Disabled by default, increases smaller mob heights so they
glitch through certain nodes. cannot glitch through certain nodes.
'mob_pathfinding_enable' Enable pathfinding. 'mob_pathfinding_enable' Enable pathfinding.
'mob_pathfinder_enable' Use pathfinder mod if available.
'mob_pathfinding_stuck_timeout' How long before stuck mobs start searching. (default 3.0) 'mob_pathfinding_stuck_timeout' How long before stuck mobs start searching. (default 3.0)
'mob_pathfinding_stuck_path_timeout' How long will mob follow path before giving up. (default 5.0) 'mob_pathfinding_stuck_path_timeout' How long will mob follow path before giving up. (default 5.0)
'mob_pathfinding_algorithm' Which pathfinding algorithm to use Dijkstra (default), A*_noprefetch (AStar_noprefetch) or A* (AStar) 'mob_pathfinding_algorithm' Which pathfinding algorithm to use Dijkstra (default), A*_noprefetch (AStar_noprefetch) or A* (AStar)
@ -830,6 +879,13 @@ External Settings for "minetest.conf"
'mob_pathfinding_searchdistance' max search distance from search positions (default 16) 'mob_pathfinding_searchdistance' max search distance from search positions (default 16)
'mob_pathfinding_max_jump' max jump height for pathfinding (default 4) 'mob_pathfinding_max_jump' max jump height for pathfinding (default 4)
'mob_pathfinding_max_drop' max drop height for pathfinding (default 6) 'mob_pathfinding_max_drop' max drop height for pathfinding (default 6)
'mobs_can_hear' Enabled by default, overrides minetest.sound_play and enables
nearby mobs to run a custom on_sound function.
'mobs_can_hear_node' Disabled by default, allows nearby nodes to hear and run a
custom on_sound function.
'mobs_disable_damage_kb' Knockback is calculated by hit damage or uses knockback value
from the weapon used, this setting lets you disable the former.
'mob_infotext' True by default, shows mob information when you hover over one.
Players can override the spawn chance for each mob registered by adding a line 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 to their minetest.conf file with a new value, the lower the value the more each
@ -845,130 +901,42 @@ mobs_animal:cow = 8000,4 <-- 4 cows per mapblock at 8000 spawn chance
mobs_monster:dirt_monster = ,20 <-- 20 dirt monsters per mapblock mobs_monster:dirt_monster = ,20 <-- 20 dirt monsters per mapblock
Node Sounds
-----------
Mobs Redo will detect wether the Default mod or MineClone/VoxeLibre mod is active and
store whichever sound set is available inside the following to save any mob mobs
having to detect it themselves:
mobs.node_sound_defaults()
mobs.node_sound_stone_defaults()
mobs.node_sound_dirt_defaults()
mobs.node_sound_sand_defaults()
mobs.node_sound_gravel_defaults()
mobs.node_sound_wood_defaults()
mobs.node_sound_leaves_defaults()
mobs.node_sound_ice_defaults()
mobs.node_sound_metal_defaults()
mobs.node_sound_water_defaults()
mobs.node_sound_snow_defaults()
mobs.node_sound_glass_defaults()
Rideable Horse Example Mob Rideable Horse Example Mob
-------------------------- --------------------------
mobs:register_mob("mob_horse:horse", { See mob_horse mod https://codeberg.org/tenplus1/mob_horse
type = "animal",
visual = "mesh",
visual_size = {x = 1.20, y = 1.20},
mesh = "mobs_horse.x",
collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.25, 0.4},
animation = {
speed_normal = 15,
speed_run = 30,
stand_start = 25,
stand_end = 75,
walk_start = 75,
walk_end = 100,
run_start = 75,
run_end = 100,
},
textures = {
{"mobs_horse.png"},
{"mobs_horsepeg.png"},
{"mobs_horseara.png"}
},
fear_height = 3,
runaway = true,
fly = false,
walk_chance = 60,
view_range = 5,
follow = {"farming:wheat"},
passive = true,
hp_min = 12,
hp_max = 16,
armor = 200,
lava_damage = 5,
fall_damage = 5,
water_damage = 1,
makes_footstep_sound = true,
drops = {
{name = "mobs:meat_raw", chance = 1, min = 2, max = 3}
},
sounds = {
random = "horse_neigh.ogg",
damage = "horse_whinney.ogg",
},
do_custom = function(self, dtime)
-- set needed values if not already present External Functions
if not self.v2 then ------------------
self.v2 = 0
self.max_speed_forward = 6
self.max_speed_reverse = 2
self.accel = 6
self.terrain_type = 3
self.driver_attach_at = {x = 0, y = 20, z = -2}
self.driver_eye_offset = {x = 0, y = 3, z = 0}
self.driver_scale = {x = 1, y = 1}
end
-- if driver present allow control of horse These are a list of utility functions that can be called from 3rd party mods.
if self.driver then
mobs.drive(self, "walk", "stand", false, dtime) mobs:alias_mob(old_name, new_name)
mobs:is_invisible(self, player_name)
return false -- skip rest of mob functions mobs:is_dangerous(self, nodename)
end mobs:yaw_to_pos(self, target, rotation_steps)
mobs:line_of_sight(self, pos1, pos2)
return true mobs:set_animation(self, animation)
end, mobs:yaw(self, yaw, rotation_steps)
on_die = function(self, pos)
-- drop saddle when horse is killed while riding
-- also detach from horse properly
if self.driver then
minetest.add_item(pos, "mobs:saddle")
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end
end,
on_rightclick = function(self, clicker)
-- make sure player is clicking
if not clicker or not clicker:is_player() then
return
end
-- feed, tame or heal horse
if mobs:feed_tame(self, clicker, 10, true, true) then
return
end
-- make sure tamed horse is being clicked by owner only
if self.tamed and self.owner == clicker:get_player_name() then
local inv = clicker:get_inventory()
-- detatch player already riding horse
if self.driver and clicker == self.driver then
mobs.detach(clicker, {x = 1, y = 0, z = 1})
-- add saddle back to inventory
if inv:room_for_item("main", "mobs:saddle") then
inv:add_item("main", "mobs:saddle")
else
minetest.add_item(clicker.get_pos(), "mobs:saddle")
end
-- attach player to horse
elseif not self.driver
and clicker:get_wielded_item():get_name() == "mobs:saddle" then
self.object:set_properties({stepheight = 1.1})
mobs.attach(self, clicker)
-- take saddle from inventory
inv:remove_item("main", "mobs:saddle")
end
end
-- used to capture horse with magic lasso
mobs:capture_mob(self, clicker, 0, 0, 80, false, nil)
end
})

41
compatibility.lua Normal file
View File

@ -0,0 +1,41 @@
-- called after mob registration to check for older settings
function mobs.compatibility_check(self)
-- simple mobs rotation setting
if self.drawtype == "side" then self.rotate = math.rad(90) end
-- replace floats var from number to bool
if self.floats == 1 then self.floats = true
elseif self.floats == 0 then self.floats = false end
end
-- deprecated functions
function mobs:yaw(entity, yaw, delay)
entity:set_yaw(yaw, delay)
end
function mobs:set_animation(entity, anim)
entity:set_animation(anim)
end
function mobs:line_of_sight(entity, pos1, pos2)
return entity:line_of_sight(pos1, pos2)
end
function mobs:yaw_to_pos(entity, target, rot)
return entity:yaw_to_pos(target, rot)
end
function mobs:register_spawn(name, nodes, max_light, min_light, chance,
active_object_count, max_height, day_toggle)
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
chance, active_object_count, -31000, max_height, day_toggle)
end
function mobs:explosion(pos, radius)
mobs:boom({sounds = {explode = "tnt_explode"}}, pos, radius, radius, "mobs_tnt_smoke.png")
end

View File

@ -1,12 +1,52 @@
local S = mobs.translate local S = core.get_translator("mobs")
local FS = function(...) return minetest.formspec_escape(S(...)) end local FS = function(...) return core.formspec_escape(S(...)) end
local mc2 = minetest.get_modpath("mcl_core") local mc2 = core.get_modpath("mcl_core")
local mod_def = core.get_modpath("default")
-- determine which sounds to use, default or mcl_sounds
local function sound_helper(snd)
mobs[snd] = (mod_def and default[snd]) or (mc2 and mcl_sounds[snd])
or function() return {} end
end
sound_helper("node_sound_defaults")
sound_helper("node_sound_stone_defaults")
sound_helper("node_sound_dirt_defaults")
sound_helper("node_sound_sand_defaults")
sound_helper("node_sound_gravel_defaults")
sound_helper("node_sound_wood_defaults")
sound_helper("node_sound_leaves_defaults")
sound_helper("node_sound_ice_defaults")
sound_helper("node_sound_metal_defaults")
sound_helper("node_sound_water_defaults")
sound_helper("node_sound_snow_defaults")
sound_helper("node_sound_glass_defaults")
-- helper function to add {eatable} group to food items
function mobs.add_eatable(item, hp)
local def = core.registered_items[item]
if def then
local groups = table.copy(def.groups) or {}
groups.eatable = hp ; groups.flammable = 2
core.override_item(item, {groups = groups})
end
end
-- recipe items -- recipe items
local items = { local items = {
paper = mc2 and "mcl_core:paper" or "default:paper", paper = mc2 and "mcl_core:paper" or "default:paper",
dye_black = mc2 and "mcl_dye:black" or "dye:black", dye_black = mc2 and "mcl_dye:black" or "dye:black",
dye_red = mc2 and "mcl_dye:red" or "dye:red",
string = mc2 and "mcl_mobitems:string" or "farming:string", string = mc2 and "mcl_mobitems:string" or "farming:string",
stick = mc2 and "mcl_core:stick" or "default:stick", stick = mc2 and "mcl_core:stick" or "default:stick",
diamond = mc2 and "mcl_core:diamond" or "default:diamond", diamond = mc2 and "mcl_core:diamond" or "default:diamond",
@ -19,16 +59,18 @@ local items = {
fence_wood = mc2 and "group:fence_wood" or "default:fence_wood", fence_wood = mc2 and "group:fence_wood" or "default:fence_wood",
meat_raw = mc2 and "mcl_mobitems:beef" or "group:food_meat_raw", meat_raw = mc2 and "mcl_mobitems:beef" or "group:food_meat_raw",
meat_cooked = mc2 and "mcl_mobitems:cooked_beef" or "group:food_meat", meat_cooked = mc2 and "mcl_mobitems:cooked_beef" or "group:food_meat",
obsidian = mc2 and "mcl_core:obsidian" or "default:obsidian"
} }
-- name tag -- name tag
minetest.register_craftitem("mobs:nametag", {
description = S("Name Tag"), core.register_craftitem("mobs:nametag", {
description = S("Name Tag") .. " " .. S("\nRight-click Mobs Redo mob to apply"),
inventory_image = "mobs_nametag.png", inventory_image = "mobs_nametag.png",
groups = {flammable = 2, nametag = 1} groups = {flammable = 2, nametag = 1}
}) })
minetest.register_craft({ core.register_craft({
output = "mobs:nametag", output = "mobs:nametag",
recipe = { recipe = {
{ items.paper, items.dye_black, items.string } { items.paper, items.dye_black, items.string }
@ -36,29 +78,36 @@ minetest.register_craft({
}) })
-- leather -- leather
minetest.register_craftitem("mobs:leather", {
core.register_craftitem("mobs:leather", {
description = S("Leather"), description = S("Leather"),
inventory_image = "mobs_leather.png", inventory_image = "mobs_leather.png",
groups = {flammable = 2, leather = 1} groups = {flammable = 2, leather = 1}
}) })
-- raw meat -- raw meat
minetest.register_craftitem("mobs:meat_raw", {
core.register_craftitem("mobs:meat_raw", {
description = S("Raw Meat"), description = S("Raw Meat"),
inventory_image = "mobs_meat_raw.png", inventory_image = "mobs_meat_raw.png",
on_use = minetest.item_eat(3), on_use = core.item_eat(3),
groups = {food_meat_raw = 1, flammable = 2} groups = {food_meat_raw = 1}
}) })
mobs.add_eatable("mobs:meat_raw", 3)
-- cooked meat -- cooked meat
minetest.register_craftitem("mobs:meat", {
core.register_craftitem("mobs:meat", {
description = S("Meat"), description = S("Meat"),
inventory_image = "mobs_meat.png", inventory_image = "mobs_meat.png",
on_use = minetest.item_eat(8), on_use = core.item_eat(8),
groups = {food_meat = 1, flammable = 2} groups = {food_meat = 1}
}) })
minetest.register_craft({ mobs.add_eatable("mobs:meat", 8)
core.register_craft({
type = "cooking", type = "cooking",
output = "mobs:meat", output = "mobs:meat",
recipe = "mobs:meat_raw", recipe = "mobs:meat_raw",
@ -66,13 +115,14 @@ minetest.register_craft({
}) })
-- lasso -- lasso
minetest.register_tool("mobs:lasso", {
core.register_tool("mobs:lasso", {
description = S("Lasso (right-click animal to put in inventory)"), description = S("Lasso (right-click animal to put in inventory)"),
inventory_image = "mobs_magic_lasso.png", inventory_image = "mobs_magic_lasso.png",
groups = {flammable = 2} groups = {flammable = 2}
}) })
minetest.register_craft({ core.register_craft({
output = "mobs:lasso", output = "mobs:lasso",
recipe = { recipe = {
{ items.string, "", items.string}, { items.string, "", items.string},
@ -81,16 +131,17 @@ minetest.register_craft({
} }
}) })
minetest.register_alias("mobs:magic_lasso", "mobs:lasso") core.register_alias("mobs:magic_lasso", "mobs:lasso")
-- net -- net
minetest.register_tool("mobs:net", {
core.register_tool("mobs:net", {
description = S("Net (right-click animal to put in inventory)"), description = S("Net (right-click animal to put in inventory)"),
inventory_image = "mobs_net.png", inventory_image = "mobs_net.png",
groups = {flammable = 2} groups = {flammable = 2}
}) })
minetest.register_craft({ core.register_craft({
output = "mobs:net", output = "mobs:net",
recipe = { recipe = {
{ items.stick, "", items.stick }, { items.stick, "", items.stick },
@ -100,13 +151,14 @@ minetest.register_craft({
}) })
-- shears (right click to shear animal) -- shears (right click to shear animal)
minetest.register_tool("mobs:shears", {
core.register_tool("mobs:shears", {
description = S("Steel Shears (right-click to shear)"), description = S("Steel Shears (right-click to shear)"),
inventory_image = "mobs_shears.png", inventory_image = "mobs_shears.png",
groups = {flammable = 2} groups = {flammable = 2}
}) })
minetest.register_craft({ core.register_craft({
output = "mobs:shears", output = "mobs:shears",
recipe = { recipe = {
{ "", items.steel_ingot, "" }, { "", items.steel_ingot, "" },
@ -115,13 +167,14 @@ minetest.register_craft({
}) })
-- protection rune -- protection rune
minetest.register_craftitem("mobs:protector", {
core.register_craftitem("mobs:protector", {
description = S("Mob Protection Rune"), description = S("Mob Protection Rune"),
inventory_image = "mobs_protector.png", inventory_image = "mobs_protector.png",
groups = {flammable = 2} groups = {flammable = 2}
}) })
minetest.register_craft({ core.register_craft({
output = "mobs:protector", output = "mobs:protector",
recipe = { recipe = {
{ items.stone, items.stone, items.stone }, { items.stone, items.stone, items.stone },
@ -130,14 +183,15 @@ minetest.register_craft({
} }
}) })
-- level 2 protection rune -- protection rune (level 2)
minetest.register_craftitem("mobs:protector2", {
core.register_craftitem("mobs:protector2", {
description = S("Mob Protection Rune (Level 2)"), description = S("Mob Protection Rune (Level 2)"),
inventory_image = "mobs_protector2.png", inventory_image = "mobs_protector2.png",
groups = {flammable = 2} groups = {flammable = 2}
}) })
minetest.register_craft({ core.register_craft({
output = "mobs:protector2", output = "mobs:protector2",
recipe = { recipe = {
{ "mobs:protector", items.mese_crystal, "mobs:protector" }, { "mobs:protector", items.mese_crystal, "mobs:protector" },
@ -146,68 +200,75 @@ minetest.register_craft({
} }
}) })
-- mob repellent node
core.register_node("mobs:mob_repellent", {
description = S("Mob Repellent (Stops mobs spawning within 16 block radius)"),
tiles = {"mobs_repellent.png"},
is_ground_content = false,
groups = {handy = 1, cracky = 3},
sounds = mobs.node_sound_stone_defaults()
})
core.register_craft({
output = "mobs:mob_repellent",
recipe = {
{ items.obsidian, items.dye_red, items.obsidian },
{ items.obsidian, "mobs:protector", items.obsidian },
{ items.obsidian, items.obsidian, items.obsidian }
}
})
-- saddle -- saddle
minetest.register_craftitem("mobs:saddle", {
core.register_craftitem("mobs:saddle", {
description = S("Saddle"), description = S("Saddle"),
inventory_image = "mobs_saddle.png", inventory_image = "mobs_saddle.png",
groups = {flammable = 2, saddle = 1} groups = {flammable = 2, saddle = 1}
}) })
minetest.register_craft({ core.register_craft({
output = "mobs:saddle", output = "mobs:saddle",
recipe = { recipe = {
{"mobs:leather", "mobs:leather", "mobs:leather"}, {"group:leather", "group:leather", "group:leather"},
{"mobs:leather", items.steel_ingot, "mobs:leather"}, {"group:leather", items.steel_ingot, "group:leather"},
{"mobs:leather", items.steel_ingot, "mobs:leather"} {"group:leather", items.steel_ingot, "group:leather"}
} }
}) })
-- register mob fence if default found
-- make sure we can register fences
local mod_def = minetest.get_modpath("default")
if mod_def and default.register_fence then if mod_def and default.register_fence then
-- mob fence (looks like normal fence but collision is 2 high) -- mob fence (looks like normal fence but collision is 2 high)
default.register_fence("mobs:fence_wood", { default.register_fence("mobs:fence_wood", {
description = S("Mob Fence"), description = S("Mob Fence"),
texture = "default_wood.png", texture = "default_wood.png",
material = "default:fence_wood", material = "default:fence_wood",
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
sounds = mod_def and default.node_sound_wood_defaults(), sounds = mobs.node_sound_wood_defaults(),
collision_box = { collision_box = {
type = "fixed", type = "fixed", fixed = {{-0.5, -0.5, -0.5, 0.5, 1.9, 0.5}}
fixed = {
{-0.5, -0.5, -0.5, 0.5, 1.9, 0.5},
} }
} })
})
end end
-- mob fence top (has enlarged collisionbox to stop mobs getting over) -- mob fence top (has enlarged collisionbox to stop mobs getting over)
minetest.register_node("mobs:fence_top", {
core.register_node("mobs:fence_top", {
description = S("Mob Fence Top"), description = S("Mob Fence Top"),
drawtype = "nodebox", drawtype = "nodebox",
tiles = {"default_wood.png"}, tiles = {"default_wood.png"},
paramtype = "light", paramtype = "light",
is_ground_content = false, is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, axey = 1},
sounds = mod_def and default.node_sound_wood_defaults(), sounds = mobs.node_sound_wood_defaults(),
node_box = { node_box = {type = "fixed", fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2}},
type = "fixed", collision_box = {type = "fixed", fixed = {-0.4, -1.5, -0.4, 0.4, 0, 0.4}},
fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2} selection_box = {type = "fixed", fixed = {-0.4, -1.5, -0.4, 0.4, 0, 0.4}}
},
collision_box = {
type = "fixed",
fixed = {-0.4, -1.5, -0.4, 0.4, 0, 0.4}
},
selection_box = {
type = "fixed",
fixed = {-0.4, -1.5, -0.4, 0.4, 0, 0.4}
}
}) })
minetest.register_craft({ core.register_craft({
output = "mobs:fence_top 12", output = "mobs:fence_top 12",
recipe = { recipe = {
{"group:wood", "group:wood", "group:wood"}, {"group:wood", "group:wood", "group:wood"},
@ -215,49 +276,15 @@ minetest.register_craft({
} }
}) })
-- items that can be used as fuel -- items that can be used as fuel
minetest.register_craft({
type = "fuel",
recipe = "mobs:nametag",
burntime = 3
})
minetest.register_craft({ core.register_craft({type = "fuel", recipe = "mobs:nametag", burntime = 3})
type = "fuel", core.register_craft({type = "fuel", recipe = "mobs:lasso", burntime = 7})
recipe = "mobs:lasso", core.register_craft({type = "fuel", recipe = "mobs:net", burntime = 8})
burntime = 7 core.register_craft({type = "fuel", recipe = "mobs:leather", burntime = 4})
}) core.register_craft({type = "fuel", recipe = "mobs:saddle", burntime = 7})
core.register_craft({type = "fuel", recipe = "mobs:fence_wood", burntime = 7})
minetest.register_craft({ core.register_craft({type = "fuel", recipe = "mobs:fence_top", burntime = 2})
type = "fuel",
recipe = "mobs:net",
burntime = 8
})
minetest.register_craft({
type = "fuel",
recipe = "mobs:leather",
burntime = 4
})
minetest.register_craft({
type = "fuel",
recipe = "mobs:saddle",
burntime = 7
})
minetest.register_craft({
type = "fuel",
recipe = "mobs:fence_wood",
burntime = 7
})
minetest.register_craft({
type = "fuel",
recipe = "mobs:fence_top",
burntime = 2
})
-- this tool spawns same mob and adds owner, protected, nametag info -- this tool spawns same mob and adds owner, protected, nametag info
@ -266,7 +293,7 @@ minetest.register_craft({
local tex_obj local tex_obj
minetest.register_tool(":mobs:mob_reset_stick", { core.register_tool(":mobs:mob_reset_stick", {
description = S("Mob Reset Stick"), description = S("Mob Reset Stick"),
inventory_image = "default_stick.png^[colorize:#ff000050", inventory_image = "default_stick.png^[colorize:#ff000050",
stack_max = 1, stack_max = 1,
@ -274,12 +301,9 @@ minetest.register_tool(":mobs:mob_reset_stick", {
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "object" then if pointed_thing.type ~= "object" then return end
return
end
local obj = pointed_thing.ref local obj = pointed_thing.ref
local control = user:get_player_control() local control = user:get_player_control()
local sneak = control and control.sneak local sneak = control and control.sneak
@ -287,7 +311,7 @@ minetest.register_tool(":mobs:mob_reset_stick", {
if obj and not sneak then if obj and not sneak then
local self = obj:get_luaentity() local self = obj:get_luaentity()
local obj2 = minetest.add_entity(obj:get_pos(), self.name) local obj2 = core.add_entity(obj:get_pos(), self.name)
if obj2 then if obj2 then
@ -319,13 +343,11 @@ minetest.register_tool(":mobs:mob_reset_stick", {
-- get base texture -- get base texture
local bt = tex_obj:get_luaentity().base_texture[1] local bt = tex_obj:get_luaentity().base_texture[1]
if type(bt) ~= "string" then if type(bt) ~= "string" then bt = "" end
bt = ""
end
local name = user:get_player_name() local name = user:get_player_name()
minetest.show_formspec(name, "mobs_texture", "size[8,4]" core.show_formspec(name, "mobs_texture", "size[8,4]"
.. "field[0.5,1;7.5,0;name;" .. "field[0.5,1;7.5,0;name;"
.. FS("Enter texture:") .. ";" .. bt .. "]" .. FS("Enter texture:") .. ";" .. bt .. "]"
.. "button_exit[2.5,3.5;3,1;mob_texture_change;" .. "button_exit[2.5,3.5;3,1;mob_texture_change;"
@ -334,30 +356,21 @@ minetest.register_tool(":mobs:mob_reset_stick", {
end end
}) })
minetest.register_on_player_receive_fields(function(player, formname, fields) core.register_on_player_receive_fields(function(player, formname, fields)
-- right-clicked with nametag and name entered? -- right-clicked with nametag and name entered?
if formname == "mobs_texture" if formname == "mobs_texture" and fields.name and fields.name ~= "" then
and fields.name
and fields.name ~= "" then
-- does mob still exist? -- does mob still exist?
if not tex_obj if not tex_obj or not tex_obj:get_luaentity() then return end
or not tex_obj:get_luaentity() then
return
end
-- make sure nametag is being used to name mob -- make sure nametag is being used to name mob
local item = player:get_wielded_item() local item = player:get_wielded_item()
if item:get_name() ~= "mobs:mob_reset_stick" then if item:get_name() ~= "mobs:mob_reset_stick" then return end
return
end
-- limit name entered to 64 characters long -- limit name entered to 64 characters long
if fields.name:len() > 64 then if fields.name:len() > 64 then fields.name = fields.name:sub(1, 64) end
fields.name = fields.name:sub(1, 64)
end
-- update texture -- update texture
local self = tex_obj:get_luaentity() local self = tex_obj:get_luaentity()
@ -371,19 +384,24 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end end
end) end)
-- Meat Block -- Meat Block
minetest.register_node("mobs:meatblock", {
core.register_node("mobs:meatblock", {
description = S("Meat Block"), description = S("Meat Block"),
tiles = {"mobs_meat_top.png", "mobs_meat_bottom.png", "mobs_meat_side.png"}, tiles = {"mobs_meat_top.png", "mobs_meat_bottom.png", "mobs_meat_side.png"},
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {choppy = 1, oddly_breakable_by_hand = 1, flammable = 2}, groups = {choppy = 1, oddly_breakable_by_hand = 1, axey = 1, handy = 1},
sounds = mod_def and default.node_sound_leaves_defaults(), is_ground_content = false,
on_place = minetest.rotate_node, sounds = mobs.node_sound_dirt_defaults(),
on_use = minetest.item_eat(20) on_place = core.rotate_node,
on_use = core.item_eat(20),
_mcl_hardness = 0.8,
_mcl_blast_resistance = 1
}) })
minetest.register_craft({ mobs.add_eatable("mobs:meatblock", 20)
core.register_craft({
output = "mobs:meatblock", output = "mobs:meatblock",
recipe = { recipe = {
{ items.meat_cooked, items.meat_cooked, items.meat_cooked }, { items.meat_cooked, items.meat_cooked, items.meat_cooked },
@ -393,17 +411,23 @@ minetest.register_craft({
}) })
-- Meat Block (raw) -- Meat Block (raw)
minetest.register_node("mobs:meatblock_raw", {
core.register_node("mobs:meatblock_raw", {
description = S("Raw Meat Block"), description = S("Raw Meat Block"),
tiles = {"mobs_meat_raw_top.png", "mobs_meat_raw_bottom.png", "mobs_meat_raw_side.png"}, tiles = {"mobs_meat_raw_top.png", "mobs_meat_raw_bottom.png", "mobs_meat_raw_side.png"},
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {choppy = 1, oddly_breakable_by_hand = 1, flammable = 2}, groups = {choppy = 1, oddly_breakable_by_hand = 1, axey = 1, handy = 1},
sounds = mod_def and default.node_sound_leaves_defaults(), is_ground_content = false,
on_place = minetest.rotate_node, sounds = mobs.node_sound_dirt_defaults(),
on_use = minetest.item_eat(20) on_place = core.rotate_node,
on_use = core.item_eat(20),
_mcl_hardness = 0.8,
_mcl_blast_resistance = 1
}) })
minetest.register_craft({ mobs.add_eatable("mobs:meatblock_raw", 20)
core.register_craft({
output = "mobs:meatblock_raw", output = "mobs:meatblock_raw",
recipe = { recipe = {
{ items.meat_raw, items.meat_raw, items.meat_raw }, { items.meat_raw, items.meat_raw, items.meat_raw },
@ -412,9 +436,65 @@ minetest.register_craft({
} }
}) })
minetest.register_craft({ core.register_craft({
type = "cooking", type = "cooking",
output = "mobs:meatblock", output = "mobs:meatblock",
recipe = "mobs:meatblock_raw", recipe = "mobs:meatblock_raw",
cooktime = 30 cooktime = 30
}) })
-- hearing vines (if mesecons active it acts like blinkyplant)
local mod_mese = core.get_modpath("mesecons")
core.register_node("mobs:hearing_vines", {
description = S("Hearing Vines"),
drawtype = "firelike",
waving = 1,
tiles = {"mobs_hearing_vines.png"},
inventory_image = "mobs_hearing_vines.png",
wield_image = "mobs_hearing_vines.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
buildable_to = true,
groups = {snappy = 3, flammable = 3, attached_node = 1, on_sound = 1},
sounds = mobs.node_sound_leaves_defaults(),
selection_box = {
type = "fixed", fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -0.25, 6 / 16},
},
on_sound = function(pos, def)
if def.loudness > 0.5 then
core.set_node(pos, {name = "mobs:hearing_vines_active"})
end
end
})
core.register_node("mobs:hearing_vines_active", {
description = S("Active Hearing Vines"),
drawtype = "firelike",
waving = 1,
tiles = {"mobs_hearing_vines_active.png"},
inventory_image = "mobs_hearing_vines_active.png",
wield_image = "mobs_hearing_vines_active.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
buildable_to = true,
light_source = 1,
damage_per_second = 4,
drop = "mobs:hearing_vines",
groups = {snappy = 3, flammable = 3, attached_node = 1, not_in_creative_inventory = 1},
sounds = mobs.node_sound_leaves_defaults(),
selection_box = {
type = "fixed", fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -0.25, 6 / 16},
},
on_construct = function(pos)
core.get_node_timer(pos):start(1)
if mod_mese then mesecon.receptor_on(pos) end
end,
on_timer = function(pos)
core.set_node(pos, {name = "mobs:hearing_vines"})
if mod_mese then mesecon.receptor_off(pos) end
end
})

View File

@ -1,29 +1,38 @@
local path = minetest.get_modpath("mobs") local S = core.get_translator("mobs")
-- Peaceful player privilege -- peaceful player privilege
minetest.register_privilege("peaceful_player", {
core.register_privilege("peaceful_player", {
description = "Prevents Mobs Redo mobs from attacking player", description = "Prevents Mobs Redo mobs from attacking player",
give_to_singleplayer = false give_to_singleplayer = false
}) })
-- fallback node
-- Mob API core.register_node("mobs:fallback_node", {
dofile(path .. "/api.lua") description = S("Fallback Node"),
tiles = {"mobs_fallback.png"},
is_ground_content = false,
groups = {handy = 1, crumbly = 3, not_in_creative_inventory = 1},
drop = ""
})
-- Rideable Mobs
dofile(path .. "/mount.lua")
-- Mob Items local path = core.get_modpath("mobs")
dofile(path .. "/crafts.lua")
-- Mob Spawner dofile(path .. "/api.lua") -- mob API
dofile(path .. "/spawner.lua")
dofile(path .. "/mount.lua") -- rideable mobs
dofile(path .. "/crafts.lua") -- items and crafts
dofile(path .. "/spawner.lua") -- mob spawner
-- Lucky Blocks -- Lucky Blocks
if minetest.get_modpath("lucky_block") then
if core.get_modpath("lucky_block") then
dofile(path .. "/lucky_block.lua") dofile(path .. "/lucky_block.lua")
end end
print("[MOD] Mobs Redo loaded") print("[MOD] Mobs Redo loaded")

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016 TenPlus1 Copyright (c) 2025 TenPlus1
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -20,9 +20,15 @@ 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
Textures borrowed from minetest_game (CC BY-SA 3.0):
mobs_tnt_smoke.png
mobs_bubble_particle.png
mobs_heart_particle.png
Textures under CC0 license by TenPlus1 Textures under CC0 license by TenPlus1
mobs_fallback.png is dirt texture from original Minetest (CC-BY SA 3.0)
ShadowNinja (CC BY-SA 3.0): ShadowNinja (CC BY-SA 3.0):
tnt_smoke.png tnt_smoke.png

View File

@ -26,7 +26,7 @@ Mob Fence=Kreaturen Zaun
Mob Fence Top=Kreaturen Zaun Oberteil Mob Fence Top=Kreaturen Zaun Oberteil
Mob Reset Stick=Kreatur reset Stock Mob Reset Stick=Kreatur reset Stock
Meat Block=Fleischblock Meat Block=Fleischblock
Raw Meat Block=Rohfleisch Blokc Raw Meat Block=Roher Fleischblock
Enter texture:=Textur eingeben: Enter texture:=Textur eingeben:
Change=Ändern Change=Ändern
Mob Spawner=Kreaturenspawner Mob Spawner=Kreaturenspawner

38
locale/mobs.pt_BR.tr Normal file
View File

@ -0,0 +1,38 @@
# textdomain: mobs
** Peaceful Mode Active - No Monsters Will Spawn=
Active Mob Limit Reached!=Limite de Mob Ativo Atingido!
Mob has been protected!=Mob foi protegido
@1 (Tamed)=@1 (Domesticado)
Not tamed!=Não domesticado!
@1 is owner!=Dono @1!
Missed!=Faltou!
Already protected!=
@1 has been tamed!=@1 foi domesticado!
@1 follows:=@1 Segue:
@1 mobs removed.=@1 mobs removido.
Enter name:=Insira um nome:
Rename=Renomear
Name Tag=Etiqueta
Leather=Couro
Raw Meat=Carne crua
Meat=Carne
Lasso (right-click animal to put in inventory)=Laço (clique-direito no animal para por no inventario)
Net (right-click animal to put in inventory)=Net (clique-direito no animal para por no inventario)
Steel Shears (right-click to shear)=Tesoura de Aço (clique-direito para tosquiar)
Mob Protection Rune=Runa de Proteção para Mob
Mob Protection Rune (Level 2)=Runa de Proteção para Mob (Nivel 2)
Saddle=Sela
Mob Fence= Cerca para mob
Mob Fence Top= Topo da cerca para mob
Mob Reset Stick=
Meat Block=Bloco de carne
Raw Meat Block=Bloco de Carne crua
Enter texture:=Insira a textura:
Change=Mudar
Mob Spawner=Spawner de mob
(mob name) (min light) (max light) (amount) (player distance) (Y offset)=(Nome do mob) (min light) (max light) (amount) (player distance) (Y offset)
Command:=Comando:
Spawner Not Active (enter settings)=Spawner Inativo (configurar)
Spawner Active (@1)=Spawner Ativo (@1)
Mob Spawner settings failed!=Configuraçao de Spawner do Mob falhou!
Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”=

View File

@ -1,38 +1,38 @@
# textdomain: mobs # textdomain: mobs
** Peaceful Mode Active - No Monsters Will Spawn=** Мирный модус активирован - монстры не спаунятся ** Peaceful Mode Active - No Monsters Will Spawn=** Мирный Режим Активен - Никаких Монстров Не Появиться
Active Mob Limit Reached!= Active Mob Limit Reached!=Лимит Активных Мобов Достигнут!
Mob has been protected!=Моб защищен! Mob has been protected!=Моб был защищён!
@1 (Tamed)=@1 (Прирученный) @1 (Tamed)=@1 (Прирученный)
Not tamed!=Не прирученный Not tamed!=Не прирученный!
@1 is owner!=@1 владелец @1 is owner!=@1 владелец!
Missed!=Промазал! Missed!=Промазал!
Already protected!=Уже защищен! Already protected!=Уже защищён!
@1 has been tamed!=@1 приручен @1 has been tamed!=@1 был приручен!
@1 follows:= @1 follows:=@1 следует:
@1 mobs removed.= @1 mobs removed.=@1 мобов удалено.
Enter name:=Введите имя: Enter name:=Введите имя:
Rename=Переименовать Rename=Переименовать
Name Tag=Новый тэг Name Tag=Новый Тег
Leather=Кожа Leather=Кожа
Raw Meat=Сырое мясо Raw Meat=Сырое Мясо
Meat=Мясо Meat=Мясо
Lasso (right-click animal to put in inventory)=Лассо (Правый клик - положить животное в инвентарь) Lasso (right-click animal to put in inventory)=Лассо (Правый клик - положить животное в инвентарь)
Net (right-click animal to put in inventory)=Сеть (Правый клик - положить животное в инвентарь) Net (right-click animal to put in inventory)=Сеть (Правый клик - положить животное в инвентарь)
Steel Shears (right-click to shear)=Ножницы (Правый клик - подстричь) Steel Shears (right-click to shear)=Железные Ножницы (Правый клик - подстричь)
Mob Protection Rune=Защитная руна мобов Mob Protection Rune=Руна Защиты Моба
Mob Protection Rune (Level 2)= Mob Protection Rune (Level 2)=Руна Защиты Моба (2 Уровень)
Saddle=Седло Saddle=Седло
Mob Fence=Забор от мобов Mob Fence=Забор для Мобов
Mob Fence Top= Mob Fence Top=Верхний Забор для Мобов
Mob Reset Stick= Mob Reset Stick=Палка Сброса Моба
Meat Block= Meat Block=Мясной Блок
Raw Meat Block= Raw Meat Block=Сырой Мясной Блок
Enter texture:= Enter texture:=Введите текстуру:
Change= Change=Изменить
Mob Spawner= Mob Spawner=Спавнер Мобов
(mob name) (min light) (max light) (amount) (player distance) (Y offset)= (mob name) (min light) (max light) (amount) (player distance) (Y offset)=(имя моба) (минимальный свет) (максимальный свет) (количество) (дистанция игрока) (смещение Y)
Command:= Command:=Команда:
Spawner Not Active (enter settings)=Спаунер не активен (введите настройки) Spawner Not Active (enter settings)=Спавнер Не Активен (введите настройки)
Spawner Active (@1)=Активные спаунер (@1) Spawner Active (@1)=Спавнер Активен (@1)
Mob Spawner settings failed!=Настройки спаунера моба провалились Mob Spawner settings failed!=Настроить Спавнер Мобов не удалось!
Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”=Синтаксис: “имя мин_свет[0-14] макс_свет[0-14] максобов_в_зоне[0 чтобы выключить] дистанция_игроков[1-20] смещение_y[-10 to 10]”

43
locale/mobs.uk.tr Normal file
View File

@ -0,0 +1,43 @@
# textdomain: mobs
Mobs Redo API=API для мобів
Simple and feature rich API to quickly add mobs into your world.=Простий і функціональний API для швидкого додавання мобів у світ.
Adds a mob api for mods to add animals or monsters etc.=Додає API для модів про тварин, монстрів тощо.
** Peaceful Mode Active - No Monsters Will Spawn=** Під час мирного режиму моби не спавняться
Active Mob Limit Reached!=Ліміт активних мобів досягнуто!
Mob has been protected!=Моб був захищений!
@1 (Tamed)=@1 (Приручений)
Not tamed!=Не приручений!
@1 is owner!=@1 є власником!
Missed!=Промах!
Already protected!=Уже захищено!
@1 has been tamed!=@1 приручено!
@1 follows:=@1 слідує:
@1 mobs removed.=@1 мобів видалено.
Enter name:=Введіть ім'я:
Rename=Перейменувати
Name Tag=Теґ для назви
Mob Repellent=Відлякувач мобів
Hearing Vines=Чутливі ліани
Leather=Шкіра
Raw Meat=Сире м'ясо
Meat=М'ясо
Lasso (right-click animal to put in inventory)=Ласо (ПКМ - покласти тварину в інвентар)
Net (right-click animal to put in inventory)=Сітка (ПКМ - покласти тварину в інвентар)
Steel Shears (right-click to shear)=Залізні ножиці (ПКМ - підстригти)
Mob Protection Rune=Руна Захисту Мобу
Mob Protection Rune (Level 2)=Руна Захисту Мобу (II рівень)
Saddle=Сідло
Mob Fence=Паркан для мобів
Mob Fence Top=Верхній паркан для мобів
Mob Reset Stick=Палиця скидання мобу
Meat Block=М'ясний блок
Raw Meat Block=Сирий м'ясний блок
Enter texture:=Введіть текстуру:
Change=Змінити
Mob Spawner=Спавнер мобів
(mob name) (min light) (max light) (amount) (player distance) (Y offset)=(ім'я мобу) (мін. світло) (макс. світло) (кількість) (дистанція гравця) (зміщення Y)
Command:=Команда:
Spawner Not Active (enter settings)=Спавнер не активний (введіть налаштування)
Spawner Active (@1)=Спавнер активний (@1)
Mob Spawner settings failed!=Не вдалося налаштувати спавнер мобів!
Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”=Синтаксис: “ім'я мін.світло[0-14] макс.світло[0-14] максобів_уоні[0 для вимкнення] дистанція_гравців[1-20] зміщення_y[-10 до 10]”

View File

@ -1,4 +1,8 @@
local S = core.get_translator("mobs")
-- add lucky blocks
lucky_block:add_blocks({ lucky_block:add_blocks({
{"dro", {"mobs:meat_raw"}, 5}, {"dro", {"mobs:meat_raw"}, 5},
{"dro", {"mobs:meat"}, 5}, {"dro", {"mobs:meat"}, 5},
@ -11,5 +15,84 @@ lucky_block:add_blocks({
{"dro", {"mobs:protector"}, 1}, {"dro", {"mobs:protector"}, 1},
{"dro", {"mobs:fence_wood"}, 10}, {"dro", {"mobs:fence_wood"}, 10},
{"dro", {"mobs:fence_top"}, 12}, {"dro", {"mobs:fence_top"}, 12},
{"lig"} {"lig"},
{"dro", {"mobs:mob_repellent"}, 1}
})
-- pint sized rune, use on tamed mob to shrink to half-size
core.register_craftitem(":mobs:pint_sized_rune", {
description = S("Pint Sized Rune"),
inventory_image = "mobs_pint_sized_rune.png",
groups = {flammable = 2},
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "object" then return end
local name = user and user:get_player_name() or ""
local tool = user and user:get_wielded_item()
local tool_name = tool:get_name()
if tool_name ~= "mobs:pint_sized_rune" then return end
local self = pointed_thing.ref:get_luaentity()
if not self._cmi_is_mob then
core.chat_send_player(name, S("Not a Mobs Redo mob!"))
return
end
if not self.tamed then
core.chat_send_player(name, S("Not tamed!"))
return
end
if self.pint_size_potion then
core.chat_send_player(name, S("Potion already applied!"))
return
end
if not mobs.is_creative(user:get_player_name()) then
tool:take_item() -- take 1 rune
user:set_wielded_item(tool)
end
local pos = self.object:get_pos()
local prop = self.object:get_properties()
vis_size = {x = self.base_size.x * .5, y = self.base_size.y * .5}
self.base_size = vis_size
colbox = {
self.base_colbox[1] * .5, self.base_colbox[2] * .5,
self.base_colbox[3] * .5, self.base_colbox[4] * .5,
self.base_colbox[5] * .5, self.base_colbox[6] * .5}
self.base_colbox = colbox
selbox = {
self.base_selbox[1] * .5, self.base_selbox[2] * .5,
self.base_selbox[3] * .5, self.base_selbox[4] * .5,
self.base_selbox[5] * .5, self.base_selbox[6] * .5}
self.base_selbox = selbox
self.object:set_properties(
{visual_size = vis_size, collisionbox = colbox, selectionbox = selbox})
self.pint_size_potion = true
pos.y = pos.y + prop.collisionbox[5]
mobs:effect(pos, 25, "mobs_protect_particle.png", 0.5, 4, 2, 15)
self:mob_sound("mobs_spell")
end
})
core.register_craft({
output = "lucky_block:pint_sized_rune",
recipe = {{"lucky_block:pint_sized_potion", "mobs:protector"}}
}) })

View File

@ -1,4 +1,4 @@
name = mobs name = mobs
description = Adds a mob api for mods to add animals or monsters etc. description = Adds a mob api for mods to add animals or monsters etc.
optional_depends = default, tnt, invisibility, lucky_block, cmi, toolranks, pathfinder, player_api, mtobjid, visual_harm_1ndicators optional_depends = default, tnt, invisibility, lucky_block, cmi, toolranks, pathfinder, player_api, mtobjid, visual_harm_1ndicators, mcl_sounds, mesecons
min_minetest_version = 5.0 min_minetest_version = 5.0

202
mount.lua
View File

@ -1,9 +1,11 @@
-- lib_mount by Blert2112 (edited by TenPlus1) -- lib_mount by Blert2112 (edited by TenPlus1)
local is_mc2 = minetest.get_modpath("mcl_mobs") -- MineClone2 check local is_mc2 = core.get_modpath("mcl_mobs") -- MineClone2 check
-- one of these is needed to ride mobs, otherwise no riding for you -- one of these is needed to ride mobs, otherwise no riding for you
if not minetest.get_modpath("player_api") and not is_mc2 then
if not core.get_modpath("player_api") and not is_mc2 then
function mobs.attach() end function mobs.attach() end
function mobs.detach() end function mobs.detach() end
@ -14,46 +16,23 @@ if not minetest.get_modpath("player_api") and not is_mc2 then
end end
-- Localise some functions -- Localise some functions
local abs, cos, floor, sin, sqrt, pi = local abs, cos, floor, sin, sqrt, pi =
math.abs, math.cos, math.floor, math.sin, math.sqrt, math.pi math.abs, math.cos, math.floor, math.sin, math.sqrt, math.pi
-- -- helper functions
-- Helper functions
--
local node_ok = function(pos, fallback)
fallback = fallback or mobs.fallback_node
local node = minetest.get_node_or_nil(pos)
if node and minetest.registered_nodes[node.name] then
return node
end
return {name = fallback}
end
local function node_is(entity) local function node_is(entity)
if not entity.standing_on then return "other" end if not entity.standing_on then return "other" end
if entity.standing_on == "air" then if entity.standing_on == "air" then return "air" end
return "air"
end
if minetest.get_item_group(entity.standing_on, "lava") ~= 0 then local def = core.registered_nodes[entity.standing_on]
return "lava"
end
if minetest.get_item_group(entity.standing_on, "liquid") ~= 0 then if def.groups.lava then return "lava" end
return "liquid" if def.groups.liquid then return "liquid" end
end if def.groups.walkable then return "walkable" end
if minetest.registered_nodes[entity.standing_on].walkable == true then
return "walkable"
end
return "other" return "other"
end end
@ -61,13 +40,9 @@ end
local function get_sign(i) local function get_sign(i)
i = i or 0 if not i or i == 0 then return 0 end
if i == 0 then return i / abs(i)
return 0
else
return i / abs(i)
end
end end
@ -89,9 +64,7 @@ local function force_detach(player)
local attached_to = player and player:get_attach() local attached_to = player and player:get_attach()
if not attached_to then if not attached_to then return end
return
end
local entity = attached_to:get_luaentity() local entity = attached_to:get_luaentity()
@ -115,50 +88,48 @@ local function force_detach(player)
player:set_properties({visual_size = {x = 1, y = 1}}) player:set_properties({visual_size = {x = 1, y = 1}})
end end
-- detach player on leaving
minetest.register_on_leaveplayer(function(player) core.register_on_leaveplayer(function(player)
force_detach(player) force_detach(player)
end) end)
-- detatch all players on shutdown
minetest.register_on_shutdown(function() core.register_on_shutdown(function()
local players = minetest.get_connected_players() local players = core.get_connected_players()
for i = 1, #players do for i = 1, #players do
force_detach(players[i]) force_detach(players[i])
end end
end) end)
-- detatch player when dead
minetest.register_on_dieplayer(function(player) core.register_on_dieplayer(function(player)
force_detach(player) force_detach(player)
return true return true
end) end)
-- find free position to detach player
-- Just for correct detaching
local function find_free_pos(pos) local function find_free_pos(pos)
local check = { local check = {
{x = 1, y = 0, z = 0}, {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 = -1, y = 1, z = 0}, {x = 0, y = 0, z = 1}, {x = 0, y = 1, z = 1},
{x = -1, y = 0, z = 0}, {x = 0, y = 0, z = -1}, {x = 0, y = 1, z = -1}
{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 for _, c in pairs(check) do
local npos = {x = pos.x + c.x, y = pos.y + c.y, z = pos.z + c.z} 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) local node = core.get_node_or_nil(npos)
if node and node.name then if node and node.name then
local def = minetest.registered_nodes[node.name] local def = core.registered_nodes[node.name]
if def and not def.walkable and def.liquidtype == "none" then if def and not def.walkable and def.liquidtype == "none" then
return npos return npos
@ -169,15 +140,16 @@ local function find_free_pos(pos)
return pos return pos
end end
-- are we a real player ? -- are we a real player ?
local function is_player(player) local function is_player(player)
if player and type(player) == "userdata" and minetest.is_player(player) then if player and type(player) == "userdata" and core.is_player(player) then
return true return true
end end
end end
-- attach player to mob entity
function mobs.attach(entity, player) function mobs.attach(entity, player)
@ -190,9 +162,7 @@ function mobs.attach(entity, player)
local rot_view = 0 local rot_view = 0
if entity.player_rotation.y == 90 then if entity.player_rotation.y == 90 then rot_view = pi / 2 end
rot_view = pi / 2
end
local attach_at = entity.driver_attach_at local attach_at = entity.driver_attach_at
local eye_offset = entity.driver_eye_offset local eye_offset = entity.driver_eye_offset
@ -211,13 +181,10 @@ function mobs.attach(entity, player)
player:set_eye_offset(eye_offset, {x = 0, y = 0, z = 0}) player:set_eye_offset(eye_offset, {x = 0, y = 0, z = 0})
player:set_properties({ player:set_properties({
visual_size = { visual_size = {x = entity.driver_scale.x, y = entity.driver_scale.y}
x = entity.driver_scale.x,
y = entity.driver_scale.y
}
}) })
minetest.after(0.2, function() core.after(0.2, function()
if is_player(player) then if is_player(player) then
@ -232,12 +199,13 @@ function mobs.attach(entity, player)
player:set_look_horizontal(entity.object:get_yaw() - rot_view) player:set_look_horizontal(entity.object:get_yaw() - rot_view)
end end
-- detatch player from mob
function mobs.detach(player) function mobs.detach(player)
force_detach(player) force_detach(player)
minetest.after(0.1, function() core.after(0.1, function()
if player and player:is_player() then if player and player:is_player() then
@ -250,15 +218,18 @@ function mobs.detach(player)
end) end)
end end
-- vars
local damage_counter = 0
-- ride mob like car or horse
function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
local yaw = entity.object:get_yaw() or 0 local yaw = entity.object:get_yaw() or 0
local rot_view = 0 local rot_view = 0
if entity.player_rotation.y == 90 then if entity.player_rotation.y == 90 then rot_view = pi / 2 end
rot_view = pi / 2
end
local acce_y = 0 local acce_y = 0
local velo = entity.object:get_velocity() ; if not velo then return end local velo = entity.object:get_velocity() ; if not velo then return end
@ -276,9 +247,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
elseif ctrl.down then -- move backwards elseif ctrl.down then -- move backwards
if entity.max_speed_reverse == 0 and entity.v == 0 then if entity.max_speed_reverse == 0 and entity.v == 0 then return end
return
end
entity.v = entity.v - entity.accel * dtime entity.v = entity.v - entity.accel * dtime
end end
@ -290,12 +259,8 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
horz = yaw horz = yaw
if ctrl.left then if ctrl.left then horz = horz + 0.05
horz = horz + 0.05 elseif ctrl.right then horz = horz - 0.05 end
elseif ctrl.right then
horz = horz - 0.05
end
else else
horz = entity.driver:get_look_horizontal() or 0 horz = entity.driver:get_look_horizontal() or 0
end end
@ -333,9 +298,8 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
if ctrl.jump then -- jump (only when standing on solid surface) if ctrl.jump then -- jump (only when standing on solid surface)
if velo.y == 0 if velo.y == 0
and entity.standing_on ~= "air" and entity.standing_on ~= "air" and entity.standing_on ~= "ignore"
and entity.standing_on ~= "ignore" and core.get_item_group(entity.standing_on, "liquid") == 0 then
and minetest.get_item_group(entity.standing_on, "liquid") == 0 then
velo.y = velo.y + entity.jump_height velo.y = velo.y + entity.jump_height
acce_y = acce_y + (acce_y * 3) + 1 acce_y = acce_y + (acce_y * 3) + 1
end end
@ -343,20 +307,45 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
end end
end end
local ni = node_is(entity)
-- env damage
if ni == "liquid" or ni == "lava" then
damage_counter = damage_counter + dtime
if damage_counter > 1 then
local damage = 0
if entity.lava_damage > 0 and ni == "lava" then
damage = entity.lava_damage
elseif entity.water_damage > 0 and ni == "liquid" then
damage = entity.water_damage
end
if damage >= 1 then
entity.object:punch(entity.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = damage}
}, nil)
end
damage_counter = 0
end
end
-- if not moving then set animation and return -- if not moving then set animation and return
if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
if stand_anim then if stand_anim then entity:set_animation(stand_anim) end
entity:set_animation(stand_anim)
end
return return
end end
-- set moving animation -- set moving animation
if moving_anim then if moving_anim then entity:set_animation(moving_anim) end
entity:set_animation(moving_anim)
end
-- Stop! -- Stop!
local s = get_sign(entity.v) local s = get_sign(entity.v)
@ -387,14 +376,11 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
p.y = p.y - 0.5 p.y = p.y - 0.5
local ni = node_is(entity)
local v = entity.v local v = entity.v
if ni == "air" then if ni == "air" then
if can_fly == true then if can_fly then new_acce.y = 0 ; acce_y = 0 end
new_acce.y = 0
end
elseif ni == "liquid" or ni == "lava" then elseif ni == "liquid" or ni == "lava" then
@ -405,7 +391,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
new_acce.y = 0 new_acce.y = 0
p.y = p.y + 1 p.y = p.y + 1
if minetest.get_item_group(entity.standing_in, "liquid") ~= 0 then if core.get_item_group(entity.standing_in, "liquid") ~= 0 then
if velo.y >= 5 then if velo.y >= 5 then
velo.y = 5 velo.y = 5
@ -441,30 +427,26 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
entity.v2 = v entity.v2 = v
end end
-- fly mob in facing direction (by D00Med, edited by TenPlus1)
-- directional flying routine by D00Med (edited by TenPlus1)
function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim) function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
local ctrl = entity.driver:get_player_control() ; if not ctrl then return end local ctrl = entity.driver:get_player_control() ; if not ctrl then return end
local velo = entity.object:get_velocity() ; if not velo then return end local velo = entity.object:get_velocity() ; if not velo then return end
local dir = entity.driver:get_look_dir() local dir = entity.driver:get_look_dir()
local yaw = entity.driver:get_look_horizontal() + 1.57 local yaw = entity.driver:get_look_horizontal() ; if not yaw then return end
yaw = yaw + 1.57 -- fix from get_yaw to get_look_horizontal
if ctrl.up then if ctrl.up then
entity.object:set_velocity({ entity.object:set_velocity(
x = dir.x * speed, {x = dir.x * speed, y = dir.y * speed + 2, z = dir.z * speed})
y = dir.y * speed + 2,
z = dir.z * speed
})
elseif ctrl.down then elseif ctrl.down then
entity.object:set_velocity({ entity.object:set_velocity(
x = -dir.x * speed, {x = -dir.x * speed, y = dir.y * speed + 2, z = -dir.z * speed})
y = dir.y * speed + 2,
z = -dir.z * speed
})
elseif not ctrl.down or ctrl.up or ctrl.jump then elseif not ctrl.down or ctrl.up or ctrl.jump then
entity.object:set_velocity({x = 0, y = -2, z = 0}) entity.object:set_velocity({x = 0, y = -2, z = 0})
@ -476,7 +458,7 @@ function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
if ctrl.LMB and ctrl.sneak and shoots then if ctrl.LMB and ctrl.sneak and shoots then
local pos = entity.object:get_pos() local pos = entity.object:get_pos()
local obj = minetest.add_entity({ local obj = core.add_entity({
x = pos.x + 0 + dir.x * 2.5, x = pos.x + 0 + dir.x * 2.5,
y = pos.y + 1.5 + dir.y, y = pos.y + 1.5 + dir.y,
z = pos.z + 0 + dir.z * 2.5}, arrow) z = pos.z + 0 + dir.z * 2.5}, arrow)
@ -486,7 +468,7 @@ function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
if ent then if ent then
ent.switch = 1 -- for mob specific arrows ent.switch = 1 -- for mob specific arrows
ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding ent.owner_id = tostring(entity.object) -- so arrows dont hurt mob
local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6} local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6}
@ -499,11 +481,9 @@ function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
end end
end end
-- change animation if stopped
if velo.x == 0 and velo.y == 0 and velo.z == 0 then if velo.x == 0 and velo.y == 0 and velo.z == 0 then
entity:set_animation(stand_anim) entity:set_animation(stand_anim) -- stopped animation
else else
-- moving animation entity:set_animation(moving_anim) -- moving animation
entity:set_animation(moving_anim)
end end
end end

View File

@ -19,11 +19,22 @@ https://forum.minetest.net/viewtopic.php?f=11&t=9917
- **Shears**. Used to right-click sheep and return 1-3 wool. - **Shears**. Used to right-click sheep and return 1-3 wool.
- **Protection Rune**. Protects tamed mobs from being harmed by other players. - **Protection Rune**. Protects tamed mobs from being harmed by other players.
- **Mob Fence and Fence Top**. Stops mobs escaping or glitching throughfences. - **Mob Fence and Fence Top**. Stops mobs escaping or glitching throughfences.
- Add mobs:mob_repellent block to stop mobs spawning within 16 node radius.
**Lucky Blocks**: 12 **Lucky Blocks**: 13
## Changelog ## Changelog
### Version 1.62
* Added ability for mobs to hear using self.on_sound() function
* Added 'mobs_can_hear' setting to turn above feature on/off
* Added {eatable} group to food items and HP in description
* Fixed timer bug when attacking
* Fixed fall damage check when riding mob
* Calculate damage before do_punch function called
* Add function to check for dropped items and for mob to do something with them
### Version 1.61 ### Version 1.61
* Fixed mob damage when riding mobs * Fixed mob damage when riding mobs
@ -31,6 +42,9 @@ https://forum.minetest.net/viewtopic.php?f=11&t=9917
* Added self.attack_patience value so mobs stop attacking unseen players * Added self.attack_patience value so mobs stop attacking unseen players
* Added self.homing so that arrows follow player when visible * Added self.homing so that arrows follow player when visible
* Added support for Visual Harm 1ndicators mod to show health bars * Added support for Visual Harm 1ndicators mod to show health bars
* Added self.node_damage flag which is true by default to enable damage_per_second node damage
* Added check for on_death() function before using mob api's own on_die() one
* Added mobs:fallback_node for when current [game] hasn't defined mapgen_dirt node
### Version 1.60 ### Version 1.60

View File

@ -56,15 +56,22 @@ enable_peaceful_player (Mobs do not attack peaceful player without reason) bool
mob_smooth_rotate (Smooth rotation for mobs) bool true mob_smooth_rotate (Smooth rotation for mobs) bool true
# Fix Mob Height if too low so they cannot escape through specific nodes # Fix Mob Height if too low so they cannot escape through specific nodes
mob_height_fix (Fix Mob Height) bool true mob_height_fix (Fix Mob Height) bool false
mob_log_spawn (Log Mob Spawning) bool false mob_log_spawn (Log Mob Spawning) bool false
# Mob hearing, when enabled will override minetest.sound_play for mobs to hear
mobs_can_hear (Enable Mob hearing) bool true
# Node hearing, when enabled will allow nodes to hear nearby sounds
mobs_can_hear_node (Enable Node hearing) bool false
# By default mobs are dealt knockback from damage, this lets you disable it
mobs_disable_damage_kb (Disable knockback from damage only) bool false
[Pathfinding] [Pathfinding]
# Enable pathfinding (default Enabled) # Enable pathfinding (default Enabled)
mob_pathfinding_enable (Enable pathfinding) bool true mob_pathfinding_enable (Enable pathfinding) bool true
# Use pathfinder mod if available (default Enabled)
mob_pathfinder_enable (Use pathfinder mod if available) bool true
# How long before stuck mobs starts searching (default 3.0) # How long before stuck mobs starts searching (default 3.0)
mob_pathfinding_stuck_timeout (How long before stuck mobs start searching) float 3.0 mob_pathfinding_stuck_timeout (How long before stuck mobs start searching) float 3.0
# How long will mob follow path before giving up (default 5.0) # How long will mob follow path before giving up (default 5.0)
@ -81,3 +88,6 @@ mob_pathfinding_searchdistance (path search distance) int 16
mob_pathfinding_max_jump (path max jump height) int 4 mob_pathfinding_max_jump (path max jump height) int 4
# max drop height for pathfinding (default 6) # max drop height for pathfinding (default 6)
mob_pathfinding_max_drop (path max drop height) int 6 mob_pathfinding_max_drop (path max drop height) int 6
# Enable mob infotext on hover
mob_infotext (Enable mob infotext on hover) bool true

View File

@ -1,30 +1,46 @@
local S = mobs.translate local S = core.get_translator("mobs")
local max_per_block = tonumber(core.settings:get("max_objects_per_block") or 99)
-- helper functions
-- are we a real player ?
local function is_player(player) local function is_player(player)
if player and type(player) == "userdata" and minetest.is_player(player) then if player and type(player) == "userdata" and core.is_player(player) then
return true return true
end end
end end
local square = math.sqrt
local get_distance = function(a, b)
if not a or not b then return 50 end -- nil check and default distance
local x, y, z = a.x - b.x, a.y - b.y, a.z - b.z
return square(x * x + y * y + z * z)
end
-- mob spawner -- mob spawner
local spawner_default = "mobs_animal:pumba 10 15 0 0 0" local spawner_default = "mobs_animal:pumba 10 15 0 0 0"
minetest.register_node("mobs:spawner", { core.register_node("mobs:spawner", {
tiles = {"mob_spawner.png"}, tiles = {"mob_spawner.png"},
drawtype = "glasslike", drawtype = "glasslike",
paramtype = "light", paramtype = "light",
walkable = true, walkable = true,
description = S("Mob Spawner"), description = S("Mob Spawner"),
groups = {cracky = 1}, groups = {cracky = 1, pickaxey = 3},
is_ground_content = false,
_mcl_hardness = 1,
_mcl_blast_resistance = 5,
sounds = mobs.node_sound_stone_defaults(),
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.get_meta(pos) local meta = core.get_meta(pos)
-- setup formspec -- setup formspec
local head = S("(mob name) (min light) (max light) (amount)" local head = S("(mob name) (min light) (max light) (amount)"
@ -32,7 +48,7 @@ minetest.register_node("mobs:spawner", {
-- text entry formspec -- text entry formspec
meta:set_string("formspec", "size[10,3.5]" meta:set_string("formspec", "size[10,3.5]"
.. "label[0.15,0.5;" .. minetest.formspec_escape(head) .. "]" .. "label[0.15,0.5;" .. core.formspec_escape(head) .. "]"
.. "field[1,2.5;8.5,0.8;text;" .. S("Command:") .. "field[1,2.5;8.5,0.8;text;" .. S("Command:")
.. ";${command}]") .. ";${command}]")
@ -42,56 +58,48 @@ minetest.register_node("mobs:spawner", {
on_right_click = function(pos, placer) on_right_click = function(pos, placer)
if minetest.is_protected(pos, placer:get_player_name()) then if core.is_protected(pos, placer:get_player_name()) then return end
return
end
end, end,
on_receive_fields = function(pos, formname, fields, sender) on_receive_fields = function(pos, formname, fields, sender)
if not fields.text or fields.text == "" then if not fields.text or fields.text == "" then return end
return
end
local meta = minetest.get_meta(pos) local meta = core.get_meta(pos)
local comm = fields.text:split(" ") local comm = fields.text:split(" ")
local name = sender:get_player_name() local name = sender:get_player_name()
if minetest.is_protected(pos, name) then if core.is_protected(pos, name) then
minetest.record_protection_violation(pos, name) core.record_protection_violation(pos, name)
return return
end end
local mob = comm[1] -- mob to spawn local mob = comm[1] or "" -- mob to spawn
local mlig = tonumber(comm[2]) -- min light local mlig = tonumber(comm[2]) -- min light
local xlig = tonumber(comm[3]) -- max light local xlig = tonumber(comm[3]) -- max light
local num = tonumber(comm[4]) -- total mobs in area local num = tonumber(comm[4]) -- total mobs in area
local pla = tonumber(comm[5]) -- player distance (0 to disable) local pla = tonumber(comm[5]) -- player distance (0 to disable)
local yof = tonumber(comm[6]) or 0 -- Y offset to spawn mob local yof = tonumber(comm[6]) or 0 -- Y offset to spawn mob
if mob and mob ~= "" and mobs.spawning_mobs[mob] if mob ~= "" and mobs.spawning_mobs[mob] and num and num >= 0 and num <= 10
and num and num >= 0 and num <= 10 and mlig and mlig >= 0 and mlig <= 15 and xlig and xlig >= 0 and xlig <= 15
and mlig and mlig >= 0 and mlig <= 15 and pla and pla >= 0 and pla <= 20 and yof and yof > -10 and yof < 10 then
and xlig and xlig >= 0 and xlig <= 15
and pla and pla >= 0 and pla <= 20
and yof and yof > -10 and yof < 10 then
meta:set_string("command", fields.text) meta:set_string("command", fields.text)
meta:set_string("infotext", S("Spawner Active (@1)", mob)) meta:set_string("infotext", S("Spawner Active (@1)", mob))
else else
minetest.chat_send_player(name, S("Mob Spawner settings failed!")) core.chat_send_player(name, S("Mob Spawner settings failed!"))
minetest.chat_send_player(name, core.chat_send_player(name,
S("Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”")) S("Syntax: “name min_light[0-14] max_light[0-14] "
.. "max_mobs_in_area[0 to disable] player_distance[1-20] "
.. "y_offset[-10 to 10]”"))
end end
end end
}) })
local max_per_block = tonumber(minetest.settings:get("max_objects_per_block") or 99)
-- spawner abm -- spawner abm
minetest.register_abm({
core.register_abm({
label = "Mob spawner node", label = "Mob spawner node",
nodenames = {"mobs:spawner"}, nodenames = {"mobs:spawner"},
interval = 10, interval = 10,
@ -101,12 +109,10 @@ minetest.register_abm({
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
-- return if too many entities already -- return if too many entities already
if active_object_count_wider >= max_per_block then if active_object_count_wider >= max_per_block then return end
return
end
-- get meta and command -- get meta and command
local meta = minetest.get_meta(pos) local meta = core.get_meta(pos)
local comm = meta:get_string("command"):split(" ") local comm = meta:get_string("command"):split(" ")
-- get settings from command -- get settings from command
@ -118,9 +124,7 @@ minetest.register_abm({
local yof = tonumber(comm[6]) or 0 local yof = tonumber(comm[6]) or 0
-- if amount is 0 then do nothing -- if amount is 0 then do nothing
if num == 0 then if num == 0 then return end
return
end
-- are we spawning a registered mob? -- are we spawning a registered mob?
if not mobs.spawning_mobs[mob] then if not mobs.spawning_mobs[mob] then
@ -129,7 +133,7 @@ minetest.register_abm({
end end
-- check objects inside 9x9 area around spawner -- check objects inside 9x9 area around spawner
local objs = minetest.get_objects_inside_radius(pos, 9) local objs = core.get_objects_inside_radius(pos, 9)
local count = 0 local count = 0
local ent local ent
@ -138,62 +142,55 @@ minetest.register_abm({
ent = obj:get_luaentity() ent = obj:get_luaentity()
if ent and ent.name and ent.name == mob then if ent and ent.name and ent.name == mob then count = count + 1 end
count = count + 1
end
end end
-- is there too many of same type? -- is there too many of same type?
if count >= num then if count >= num then return end
return
end
-- spawn mob if player detected and in range -- when player distance above 0, spawn mob if player detected and in range
if pla > 0 then if pla > 0 then
local in_range = 0 local in_range, player
local objsp = minetest.get_objects_inside_radius(pos, pla) local players = core.get_connected_players()
for _, oir in pairs(objsp) do for i = 1, #players do
if is_player(oir) then player = players[i]
in_range = 1 if get_distance(player:get_pos(), pos) <= pla then
in_range = true
break break
end end
end end
-- player not found -- player not found
if in_range == 0 then if not in_range then return end
return
end
end end
-- set medium mob usually spawns in (defaults to air) -- set medium mob usually spawns in (defaults to air)
local reg = minetest.registered_entities[mob].fly_in local reg = core.registered_entities[mob].fly_in
if not reg or type(reg) == "string" then if not reg or type(reg) == "string" then reg = {(reg or "air")} end
reg = {(reg or "air")}
end
-- find air blocks within 5 nodes of spawner -- find air blocks within 5 nodes of spawner
local air = minetest.find_nodes_in_area( local air = core.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},
{x = pos.x + 5, y = pos.y + yof, z = pos.z + 5}, reg) {x = pos.x + 5, y = pos.y + yof, z = pos.z + 5}, reg)
-- spawn in random air block -- spawn in random air block
if air and #air > 0 then if air and #air > 0 then
local pos2 = air[math.random(#air)] local pos2 = air[math.random(#air)]
local lig = minetest.get_node_light(pos2) or 0 local lig = core.get_node_light(pos2) or 0
pos2.y = pos2.y + 0.5 pos2.y = pos2.y + 0.5
-- only if light levels are within range -- only if light levels are within range
if lig >= mlig and lig <= xlig if lig >= mlig and lig <= xlig and core.registered_entities[mob] then
and minetest.registered_entities[mob] then core.add_entity(pos2, mob)
minetest.add_entity(pos2, mob)
end end
end end
end end

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

BIN
textures/mobs_fallback.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 B

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

BIN
textures/mobs_repellent.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

View File

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 202 B