1
- -- Mobs Api (17th February 2016)
1
+ -- Mobs Api (4th March 2016)
2
2
mobs = {}
3
3
mobs .mod = " redo"
4
4
@@ -20,6 +20,16 @@ local stuck_path_timeout = 10 -- how long will mob follow path before giving up
20
20
21
21
local pi = math.pi
22
22
local square = math.sqrt
23
+ local atan = function (x )
24
+
25
+ if x ~= x then
26
+ -- error("atan bassed NaN")
27
+ print (" atan based NaN" )
28
+ return 0
29
+ else
30
+ return math.atan (x )
31
+ end
32
+ end
23
33
24
34
do_attack = function (self , player )
25
35
@@ -129,6 +139,34 @@ set_animation = function(self, type)
129
139
end
130
140
end
131
141
142
+ -- check line of sight for walkers and swimmers alike
143
+ function line_of_sight_water (self , pos1 , pos2 , stepsize )
144
+
145
+ local s , pos_w = minetest .line_of_sight (pos1 , pos2 , stepsize )
146
+
147
+ -- normal walking and flying mobs can see you through air
148
+ if s == true then
149
+ return true
150
+ end
151
+
152
+ -- swimming mobs can see you through water
153
+ if s == false
154
+ and self .fly
155
+ and self .fly_in == " default:water_source" then
156
+
157
+ local nod = minetest .get_node (pos_w ).name
158
+
159
+ if nod == " default:water_source"
160
+ or nod == " default:water_flowing" then
161
+
162
+ return true
163
+ end
164
+ end
165
+
166
+ return false
167
+
168
+ end
169
+
132
170
-- particle effects
133
171
function effect (pos , amount , texture , max_size )
134
172
@@ -285,6 +323,24 @@ local function is_at_cliff(self)
285
323
return false
286
324
end
287
325
326
+ -- get node but use fallback for nil or unknown
327
+ local function node_ok (pos , fallback )
328
+
329
+ fallback = fallback or " default:dirt"
330
+
331
+ local node = minetest .get_node_or_nil (pos )
332
+
333
+ if not node then
334
+ return minetest .registered_nodes [fallback ]
335
+ end
336
+
337
+ if minetest .registered_nodes [node .name ] then
338
+ return node
339
+ end
340
+
341
+ return minetest .registered_nodes [fallback ]
342
+ end
343
+
288
344
-- environmental damage (water, lava, fire, light)
289
345
do_env_damage = function (self )
290
346
@@ -315,15 +371,16 @@ do_env_damage = function(self)
315
371
effect (pos , 5 , " tnt_smoke.png" )
316
372
end
317
373
374
+ -- what is mob standing in?
375
+ pos .y = pos .y + self .collisionbox [2 ] + 0.1 -- foot level
376
+ self .standing_in = node_ok (pos , " air" ).name
377
+ -- print ("standing in " .. self.standing_in)
378
+
318
379
if self .water_damage ~= 0
319
380
or self .lava_damage ~= 0 then
320
381
321
- pos . y = pos . y + self .collisionbox [ 2 ] + 0.1 -- foot level
382
+ local nodef = minetest . registered_nodes [ self .standing_in ]
322
383
323
- local nod = node_ok (pos , " air" ) ; -- print ("standing in "..nod.name)
324
- local nodef = minetest .registered_nodes [nod .name ]
325
-
326
- if not nodef then return end -- MFF fix crash
327
384
pos .y = pos .y + 1
328
385
329
386
-- water
@@ -338,8 +395,8 @@ do_env_damage = function(self)
338
395
-- lava or fire
339
396
if self .lava_damage ~= 0
340
397
and (nodef .groups .lava
341
- or nod . name == " fire:basic_flame"
342
- or nod . name == " fire:permanent_flame" ) then
398
+ or self . standing_in == " fire:basic_flame"
399
+ or self . standing_in == " fire:permanent_flame" ) then
343
400
344
401
self .object :set_hp (self .object :get_hp () - self .lava_damage )
345
402
@@ -462,24 +519,6 @@ function entity_physics(pos, radius, self) --/MFF (Crabman|06/23/2015)add self t
462
519
end
463
520
end
464
521
465
- -- get node but use fallback for nil or unknown
466
- function node_ok (pos , fallback )
467
-
468
- fallback = fallback or " default:dirt"
469
-
470
- local node = minetest .get_node_or_nil (pos )
471
-
472
- if not node then
473
- return minetest .registered_nodes [fallback ]
474
- end
475
-
476
- if minetest .registered_nodes [node .name ] then
477
- return node
478
- end
479
-
480
- return minetest .registered_nodes [fallback ]
481
- end
482
-
483
522
-- should mob follow what I'm holding ?
484
523
function follow_holding (self , clicker )
485
524
@@ -1117,7 +1156,8 @@ minetest.register_entity(name, {
1117
1156
-- field of view check goes here
1118
1157
1119
1158
-- choose closest player to attack
1120
- if minetest .line_of_sight (sp , p , 2 ) == true
1159
+ -- if minetest.line_of_sight(sp, p, 2) == true
1160
+ if line_of_sight_water (self , sp , p , 2 ) == true
1121
1161
and dist < min_dist then
1122
1162
min_dist = dist
1123
1163
min_player = player
@@ -1246,7 +1286,7 @@ minetest.register_entity(name, {
1246
1286
if vec .x ~= 0
1247
1287
and vec .z ~= 0 then
1248
1288
1249
- yaw = (math. atan (vec .z / vec .x ) + pi / 2 ) - self .rotate
1289
+ yaw = (atan (vec .z / vec .x ) + pi / 2 ) - self .rotate
1250
1290
1251
1291
if p .x > s .x then
1252
1292
yaw = yaw + pi
@@ -1283,6 +1323,19 @@ minetest.register_entity(name, {
1283
1323
end
1284
1324
end
1285
1325
1326
+ -- water swimmers flop when on land
1327
+ if self .fly
1328
+ and self .fly_in == " default:water_source"
1329
+ and self .standing_in ~= self .fly_in then
1330
+
1331
+ self .state = " flop"
1332
+ self .object :setvelocity ({x = 0 , y = - 5 , z = 0 })
1333
+
1334
+ set_animation (self , " stand" )
1335
+
1336
+ return
1337
+ end
1338
+
1286
1339
if self .state == " stand" then
1287
1340
1288
1341
if math.random (1 , 4 ) == 1 then
@@ -1315,7 +1368,7 @@ minetest.register_entity(name, {
1315
1368
if vec .x ~= 0
1316
1369
and vec .z ~= 0 then
1317
1370
1318
- yaw = (math. atan (vec .z / vec .x ) + pi / 2 ) - self .rotate
1371
+ yaw = (atan (vec .z / vec .x ) + pi / 2 ) - self .rotate
1319
1372
1320
1373
if lp .x > s .x then
1321
1374
yaw = yaw + pi
@@ -1350,22 +1403,6 @@ minetest.register_entity(name, {
1350
1403
local s = self .object :getpos ()
1351
1404
local lp = minetest .find_node_near (s , 1 , {" group:water" })
1352
1405
1353
- -- water swimmers cannot move out of water
1354
- if self .fly
1355
- and self .fly_in == " default:water_source"
1356
- and not lp then
1357
-
1358
- -- print ("out of water")
1359
-
1360
- set_velocity (self , 0 )
1361
-
1362
- -- change to undefined state so nothing more happens
1363
- self .state = " flop"
1364
- set_animation (self , " stand" )
1365
-
1366
- return
1367
- end
1368
-
1369
1406
-- if water nearby then turn away
1370
1407
if lp then
1371
1408
@@ -1378,7 +1415,7 @@ minetest.register_entity(name, {
1378
1415
if vec .x ~= 0
1379
1416
and vec .z ~= 0 then
1380
1417
1381
- yaw = math. atan (vec .z / vec .x ) + 3 * pi / 2 - self .rotate
1418
+ yaw = atan (vec .z / vec .x ) + 3 * pi / 2 - self .rotate
1382
1419
1383
1420
if lp .x > s .x then
1384
1421
yaw = yaw + pi
@@ -1480,7 +1517,7 @@ minetest.register_entity(name, {
1480
1517
if vec .x ~= 0
1481
1518
and vec .z ~= 0 then
1482
1519
1483
- yaw = math. atan (vec .z / vec .x ) + pi / 2 - self .rotate
1520
+ yaw = atan (vec .z / vec .x ) + pi / 2 - self .rotate
1484
1521
1485
1522
if p .x > s .x then
1486
1523
yaw = yaw + pi
@@ -1657,7 +1694,7 @@ minetest.register_entity(name, {
1657
1694
if vec .x ~= 0
1658
1695
and vec .z ~= 0 then
1659
1696
1660
- yaw = (math. atan (vec .z / vec .x ) + pi / 2 ) - self .rotate
1697
+ yaw = (atan (vec .z / vec .x ) + pi / 2 ) - self .rotate
1661
1698
1662
1699
if p .x > s .x then
1663
1700
yaw = yaw + pi
@@ -1720,7 +1757,8 @@ minetest.register_entity(name, {
1720
1757
p2 .y = p2 .y + 1.5
1721
1758
s2 .y = s2 .y + 1.5
1722
1759
1723
- if minetest .line_of_sight (p2 , s2 ) == true then
1760
+ -- if minetest.line_of_sight(p2, s2) == true then
1761
+ if line_of_sight_water (self , p2 , s2 ) == true then
1724
1762
1725
1763
-- play attack sound
1726
1764
if self .sounds .attack then
@@ -1756,7 +1794,7 @@ minetest.register_entity(name, {
1756
1794
if vec .x ~= 0
1757
1795
and vec .z ~= 0 then
1758
1796
1759
- yaw = (math. atan (vec .z / vec .x ) + pi / 2 ) - self .rotate
1797
+ yaw = (atan (vec .z / vec .x ) + pi / 2 ) - self .rotate
1760
1798
1761
1799
if p .x > s .x then
1762
1800
yaw = yaw + pi
@@ -1868,7 +1906,8 @@ minetest.register_entity(name, {
1868
1906
local up = 2
1869
1907
1870
1908
-- if already in air then dont go up anymore when hit
1871
- if v .y > 0 then
1909
+ if v .y > 0
1910
+ or self .fly then
1872
1911
up = 0
1873
1912
end
1874
1913
@@ -1896,7 +1935,7 @@ minetest.register_entity(name, {
1896
1935
if vec .x ~= 0
1897
1936
and vec .z ~= 0 then
1898
1937
1899
- local yaw = math. atan (vec .z / vec .x ) + 3 * pi / 2 - self .rotate
1938
+ local yaw = atan (vec .z / vec .x ) + 3 * pi / 2 - self .rotate
1900
1939
1901
1940
if lp .x > s .x then
1902
1941
yaw = yaw + pi
@@ -1912,14 +1951,13 @@ minetest.register_entity(name, {
1912
1951
1913
1952
-- attack puncher and call other mobs for help
1914
1953
if self .passive == false
1954
+ and self .state ~= " flop"
1915
1955
and self .child == false
1916
1956
and hitter :get_player_name () ~= self .owner then
1917
1957
1918
- -- if self.state ~= "attack" then
1919
- -- attack whoever punched mob
1920
- self .state = " "
1921
- do_attack (self , hitter )
1922
- -- end
1958
+ -- attack whoever punched mob
1959
+ self .state = " "
1960
+ do_attack (self , hitter )
1923
1961
1924
1962
-- alert others to the attack
1925
1963
local obj = nil
@@ -2031,6 +2069,7 @@ minetest.register_entity(name, {
2031
2069
self .mesh = mesh
2032
2070
self .collisionbox = colbox
2033
2071
self .visual_size = vis_size
2072
+ self .standing_in = " "
2034
2073
2035
2074
-- set anything changed above
2036
2075
self .object :set_properties (self )
@@ -2266,6 +2305,11 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
2266
2305
and data [vi ] ~= c_chest then
2267
2306
2268
2307
local n = node_ok (p ).name
2308
+ local on_blast = minetest .registered_nodes [n ].on_blast
2309
+
2310
+ if on_blast then
2311
+ return on_blast (p )
2312
+ end
2269
2313
2270
2314
if not minetest .is_protected (p , " " ) -- /MFF (Crabman|06/23/2015) re-added node protected in areas
2271
2315
and minetest .get_item_group (n , " unbreakable" ) ~= 1
@@ -2419,7 +2463,7 @@ function mobs:register_egg(mob, desc, background, addegg)
2419
2463
local invimg = background
2420
2464
2421
2465
if addegg == 1 then
2422
- invimg = invimg .. " ^mobs_chicken_egg.png"
2466
+ invimg = invimg .. " ^mobs_chicken_egg.png" -- MFF
2423
2467
end
2424
2468
2425
2469
minetest .register_craftitem (mob , {
0 commit comments