77 Commits

Author SHA1 Message Date
Jordan Irwin
b4b71f5dc8 Cleanup 2021-05-06 21:45:12 -07:00
Jordan Irwin
edb0a24809 Update README 2021-05-06 21:40:38 -07:00
Jordan Irwin
3e007b1ea6 Change to MIT license 2021-05-06 21:40:38 -07:00
Jordan Irwin
02c8bea45e Update changelog 2021-05-06 21:40:38 -07:00
Jordan Irwin
d74dfde51a Add changelog & todo list 2021-05-06 21:40:38 -07:00
Jordan Irwin
e2fe01a10b Add screenshot to README 2021-05-06 21:40:37 -07:00
Jordan Irwin
1fc949bf99 Add mode "inflate" 2021-05-06 21:40:37 -07:00
Jordan Irwin
47185f48c8 Make sneeker follow player 2021-05-06 21:40:37 -07:00
Jordan Irwin
ea4e576ee6 Re-enable "boom" (WIP) 2021-05-06 21:40:37 -07:00
Jordan Irwin
43855a6e6b Fix spawning 2021-05-06 21:40:37 -07:00
Jordan Irwin
9f061a533c Remove combat settings 2021-05-06 21:40:37 -07:00
Jordan Irwin
523492b1a4 Fix rotation 2021-05-06 21:40:37 -07:00
Jordan Irwin
692b36ba59 Cleanup 2021-05-06 21:40:37 -07:00
Jordan Irwin
0e173ccefb Only add gunpower drop if tnt mod available 2021-05-06 21:40:37 -07:00
Jordan Irwin
ae9c9c32dc Add more nodes to spawn on 2021-05-06 21:40:37 -07:00
Jordan Irwin
9046b0fad7 Begin porting to creatures (cmer) mob engine 2021-05-06 21:40:05 -07:00
Jordan Irwin
ff01e876f5 Change default settings 2021-05-06 21:35:00 -07:00
Jordan Irwin
da35fb58ac Cleanup 2021-05-06 21:34:38 -07:00
Jordan Irwin
4db155bd9b Move all settings values into settings.lua 2021-05-06 21:30:26 -07:00
Jordan Irwin
428b88bdda Cleanup logging 2021-05-06 21:28:05 -07:00
Jordan Irwin
2603c721d2 Use asm_spawneggs to create egg 2021-05-06 21:16:44 -07:00
Jordan Irwin
592e247c1c Spawn on nether:rack if nether mod available 2021-05-06 21:11:18 -07:00
Jordan Irwin
a4d47e7e6b Remove WTFPL license 2021-05-06 21:03:18 -07:00
AntumDeluge
9739add50c Set default max light for spawn to 4 2021-05-06 21:03:01 -07:00
AntumDeluge
5eb1de1627 Add settings & set max/min height for spawning:
- sneeker.spawn_minlight
  - Sets the minimum light required for spawn to occur.
- sneeker.spawn_minheight
  - Sets the lowest position at which sneeker can spawn.
- sneeker.spawn_maxheight
  - Sets the highest position at which sneeker can spawn.
2021-05-06 21:01:40 -07:00
AntumDeluge
3497f917f9 Call 'core.*' instead of 'minetest.*' 2021-05-06 20:54:51 -07:00
AntumDeluge
88794f7a8f settings: Use 'enable_debug_mods' instead of 'sneeker.debug' 2021-05-06 20:51:49 -07:00
AntumDeluge
6b94bef75e User alternate message if spawn chance is less than 1% 2021-05-06 20:49:38 -07:00
AntumDeluge
394465e515 Fix 'spawn_cap' 2021-05-06 20:45:58 -07:00
AntumDeluge
a003553309 Set default maximum spawn to 10 2021-05-06 20:42:51 -07:00
AntumDeluge
3f12094bdf Lower spawn rate & chance 2021-05-06 20:41:42 -07:00
AntumDeluge
f26ca5c2b9 Make 'spawn_cap' local to 'spawn.lua' 2021-05-06 20:39:02 -07:00
AntumDeluge
87dec04c58 Make 'spawn_maxlight' local to 'spawn.lua' 2021-05-06 20:34:18 -07:00
AntumDeluge
41bf1ae241 Set 'spawn_maxlight' to 5 for lower spawn rate 2021-05-06 20:29:43 -07:00
AntumDeluge
b271747df7 Change 'spawn_maxlight' default value to '7' 2021-05-06 20:26:20 -07:00
AntumDeluge
d12f80d1f3 Change 'spawn_interval' default to 2 minutes (120) 2021-05-06 20:25:17 -07:00
AntumDeluge
1d9c2ed3c5 Change 'spawn_chance' default to '2' (1/2 or 50%) 2021-05-06 20:23:44 -07:00
AntumDeluge
e96d9da420 Add more debugging output 2021-05-06 20:21:40 -07:00
AntumDeluge
6b8a1b7f82 Fix finding number of active entities in world 2021-05-06 20:19:08 -07:00
AntumDeluge
da60a0f9ab Don't set local 'spawnit' 2021-05-06 20:18:43 -07:00
AntumDeluge
fe42ca01db Add method 'sneeker.get_pos_string':
Returns x, y, z coordinates in a string.
2021-05-06 20:14:21 -07:00
AntumDeluge
21d78e0b65 Add debugging output in case of denied spawn 2021-05-06 20:03:37 -07:00
AntumDeluge
3a3de549bf Fix global name:
- 'sneeker' not 'sneaker'
2021-05-06 19:59:49 -07:00
AntumDeluge
58b239b4ae Minor edit to log message 2021-05-06 19:57:26 -07:00
AntumDeluge
c905656ec8 Changes to 'sneeker.log' method:
Only log message if minetest setting 'log_mods' is 'true'.
2021-05-06 19:56:00 -07:00
AntumDeluge
ea3ab21024 Change debug message in 'sneeker.log_debug' 2021-05-06 19:48:48 -07:00
AntumDeluge
23477fb85f Add debug message to display in log when turned on 2021-05-06 19:48:29 -07:00
AntumDeluge
a73dc9aa39 Put node light in local variable & add debugging output 2021-05-06 19:46:51 -07:00
AntumDeluge
a5025cdfb8 Use setting 'sneeker.spawn_maxlight' to determine node light for spawn 2021-05-06 19:44:49 -07:00
AntumDeluge
439646417a Add method 'sneaker.spawn' to spawn entity 2021-05-06 19:42:16 -07:00
AntumDeluge
1f04669a68 Do not spawn if spawn cap is reached 2021-05-06 19:42:16 -07:00
AntumDeluge
05670a46c7 Put mob & spawnegg names in 'sneeker' attributes 2021-05-06 19:41:57 -07:00
AntumDeluge
af4f5219f1 Set spawn cap at 25 2021-05-06 19:35:02 -07:00
AntumDeluge
43bfded8b2 Change settings naming convention from 'sneeker_*' to 'sneeker.*' 2021-05-06 19:33:34 -07:00
AntumDeluge
517c7afd06 Re-label to 'sneeker' 2021-05-06 19:31:05 -07:00
AntumDeluge
40f0c24552 Move settings variables & functions:
- Settings to 'settings.lua'
- Functions to 'functions.lua'
2021-05-06 19:24:36 -07:00
AntumDeluge
e2badd6a6f Add debugging setting & log method 2021-05-06 19:18:37 -07:00
AntumDeluge
58d9d44c35 Add logging messages 2021-05-06 19:13:35 -07:00
AntumDeluge
3d06833867 settingtypes.txt: Add 'sneaker_spawn_cap' 2021-05-06 19:08:46 -07:00
AntumDeluge
0b7e8b89c6 Change spawn rate:
- Use settings file to set 'chance' & 'interval'
- Set spawn chance to 1/18000 (18000)
- Set spawn interval to 40 minutes (2400)
2021-05-06 19:08:27 -07:00
AntumDeluge
beaff3d886 Add variable 'sneaker.spawn_cap':
Will set maximun number of sneakers that can be spawned in world at one
time.
2021-05-06 19:03:24 -07:00
AntumDeluge
a52acac435 Remove unnecessary variable 'time_sec' 2021-05-06 19:00:40 -07:00
AntumDeluge
c0a53e2340 Add 'sneaker.log' method 2021-05-06 19:00:17 -07:00
AntumDeluge
f838db1cef Set license for new code as CC0 2021-05-06 18:57:53 -07:00
AntumDeluge
c789f39247 Rename 'LICENSE.md' to 'LICENSE-wtfpl.txt' 2021-05-06 18:55:30 -07:00
AntumDeluge
d9602eef55 Set variables 'sneaker.modname' & 'sneaker.modpath' 2021-05-06 18:54:39 -07:00
AntumDeluge
58ac8ed83c Relabel to 'sneaker' 2021-05-06 18:35:19 -07:00
AntumDeluge
b1c3a5a590 Replace deprecated methods:
- 'setting_get' with 'settings:get'
- 'setting_getbool' with 'settings:get_bool'
2021-05-06 18:26:41 -07:00
AntumDeluge
de7cd62f17 Run spawn function every 20 minutes 2021-05-06 18:23:40 -07:00
AntumDeluge
9d4581ec5b Use 'spawneggs' & 'tnt' to craft 'creeper:spawnegg' 2021-05-06 18:21:48 -07:00
Jordan Irwin
84f6c2f3c9 Hack: check that coordinates are numbers before setting new velocity 2021-05-06 18:01:33 -07:00
Jordan Irwin
6c46f8bf7e Check that tnt is enabled 2021-05-06 18:00:40 -07:00
Jordan Irwin
45b0bf5f08 Update for Minetest 5.x API 2021-05-06 17:58:47 -07:00
Jordan Irwin
6efa22caf4 Fix line endings 2021-05-06 17:32:24 -07:00
Jordan Irwin
b88e4357f9 Add tnt as dependency 2021-05-06 17:14:03 -07:00
Jordan Irwin
cc9cb71090 Whitespace cleanup 2021-05-06 17:13:44 -07:00
Jordan Irwin
a89eb699c9 Move description & dependencies into mod.conf 2021-05-06 17:10:14 -07:00
20 changed files with 836 additions and 405 deletions

8
CHANGES.txt Normal file
View File

@@ -0,0 +1,8 @@
1.0
- Forked & renamed from Rui's original "creeper" mod.
- Updated for Minetest 5.x API.
- Changed to MIT license.
- Ported to Creatures Revived (cmer) engine.
- Spawn on more types of nodes.
- Spawn on "nether:rack" if nether mod available.

View File

@@ -1,13 +0,0 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

21
LICENSE.txt Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright © 2021 Jordan Irwin (AntumDeluge)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,8 +1,51 @@
# creeper ## Sneeker mod for Minetest
Adds some explosive nuisance.
## Forum Topic ---
- https://forum.minetest.net/viewtopic.php?t=11891 ### Description:
## License An explosive nuisance for [Minetest](http://minetest.net/).
- **Code:** WTFPL
![screenshot](screenshot.png)
---
### Licensing:
- **Code:** [MIT](LICENSE.txt)
- Original by Rui: WTFPL
---
### Usage:
Settings:
- ***sneeker.spawn_chance***
- Sets possibility for spawn.
- type: int
- default: 10000
- ***sneeker.spawn_interval***
- Sets frequency of spawn chance.
- type: int
- default: 240 (4 minutes)
- ***sneeker.spawn_minlight***
- Sets the minimum light that a node must have for spawn to occur.
- type: int
- default: 0
- ***sneeker.spawn_maxlight***
- Sets the maximum light that a node can have for spawn to occur.
- type: int
- default: 9
- ***sneeker.spawn_minheight***
- Sets the maximum light that a node can have for spawn to occur.
- type: int
- default: -31000
- ***sneeker.spawn_maxheight***
- Sets the lowest position at which sneeker can spawn.
- type: int
- default 31000
---
### Links:
- [Original forum thread](https://forum.minetest.net/viewtopic.php?t=11891)
- [Git repo](https://github.com/AntumMT/mod-sneeker)
- [Changelog](CHANGES.txt)
- [TODO](TODO.txt)

5
TODO.txt Normal file
View File

@@ -0,0 +1,5 @@
TODO:
- fix walk logic to stop before exploding
- fix sound playthrough
- remove unused setting "sneeker.spawn_cap"

View File

@@ -1 +0,0 @@
default

View File

@@ -1 +0,0 @@
Adds some explosive nuisance.

13
functions.lua Normal file
View File

@@ -0,0 +1,13 @@
-- Functions for sneeker mod
-- Spawns a sneeker entity
function sneeker.spawn(pos)
core.add_entity(pos, sneeker.mob_name)
sneeker.log("debug", "Spawned entity \"" .. sneeker.mob_name .. "\" at " .. tostring(pos.x) .. "," .. tostring(pos.y))
end
-- Retrieves pos coordinates in string value
function sneeker.get_pos_string(pos)
return "x=" .. tostring(pos.x) .. ", y=" .. tostring(pos.y) .. ", z=" .. tostring(pos.z)
end

903
init.lua
View File

@@ -1,343 +1,560 @@
creeper = {}
sneeker = {}
--[[ sneeker.modname = core.get_current_modname()
-- DISABLED!!! sneeker.modpath = core.get_modpath(sneeker.modname)
do return end
--]] dofile(sneeker.modpath .. "/settings.lua")
dofile(minetest.get_modpath("creeper").."/tnt_function.lua") sneeker.log = function(lvl, msg)
dofile(minetest.get_modpath("creeper").."/spawn.lua") if lvl == "debug" and not sneeker.debug then return end
local function jump(self,pos,direction) if not msg then
local velocity = self.object:getvelocity() msg = lvl
if minetest.registered_nodes[minetest.get_node(pos).name].climbable then lvl = nil
self.object:setvelocity({x=velocity.x,y=4,z=velocity.z}) end
return
end msg = "[" .. sneeker.modname .. "] " .. msg
if lvl == "debug" then
local spos = {x=pos.x+direction.x,y=pos.y,z=pos.z+direction.z} msg = "[DEBUG] " .. msg
local node = minetest.get_node_or_nil(spos) end
spos.y = spos.y+1
local node2 = minetest.get_node_or_nil(spos) if not lvl then
local def,def2 = {} core.log(msg)
if node and node.name then else
def = minetest.registered_items[node.name] core.log(lvl, msg)
end end
if node2 and node2.name then end
def2 = minetest.registered_items[node2.name]
end sneeker.log("debug", "Debugging is on")
if def and def.walkable
and def2 and not def2.walkable
and def.drawtype ~= "fencelike" then if core.settings:get_bool("log_mods") then
self.object:setvelocity({ core.log("action", "Loading mod \"" .. sneeker.modname .. "\" ...")
x=velocity.x*2.2, end
y=self.jump_height,
z=velocity.z*2.2 sneeker.mob_name = "sneeker:sneeker"
}) local old_spawnegg_name = "sneeker:spawnegg"
end
end local scripts = {
"functions",
local function random_turn(self) "tnt_function",
if self.turn_timer > math.random(2,5) then --"spawn",
local select_turn = math.random(1,3) }
if select_turn == 1 then
self.turn = "left" for _, script in ipairs(scripts) do
elseif select_turn == 2 then dofile(sneeker.modpath .. "/" .. script .. ".lua")
self.turn = "right" end
elseif select_turn == 3 then
self.turn = "straight" --[[
end local function jump(self, pos, direction)
self.turn_timer = 0 local velocity = self.object:get_velocity()
self.turn_speed = 0.05*math.random() if core.registered_nodes[core.get_node(pos).name].climbable then
end self.object:set_velocity({x=velocity.x, y=4, z=velocity.z})
end return
end
local def = {
hp_max = 20, local spos = {x=pos.x+direction.x, y=pos.y, z=pos.z+direction.z}
physical = true, local node = core.get_node_or_nil(spos)
collisionbox = {-0.25,-0.7,-0.25, 0.25,0.8,0.25}, spos.y = spos.y+1
visual = "mesh", local node2 = core.get_node_or_nil(spos)
mesh = "character.b3d", local def, def2 = {}
textures = {"creeper.png"}, if node and node.name then
makes_footstep_sound = false, def = core.registered_items[node.name]
end
-- Original if node2 and node2.name then
animation = { def2 = core.registered_items[node2.name]
stand_START = 0, end
stand_END = 79, if def and def.walkable
walk_START = 168, and def2 and not def2.walkable
walk_END = 187 and def.drawtype ~= "fencelike" then
}, self.object:set_velocity({
walk_speed = 1.5, x = velocity.x*2.2,
jump_height = 5, y = self.jump_height,
animation_speed = 30, z = velocity.z*2.2
knockback_level = 2 })
} end
end
def.on_activate = function(self,staticdata)
self.yaw = 0 local function random_turn(self)
self.anim = 1 if self.turn_timer > math.random(2, 5) then
self.timer = 0 local select_turn = math.random(1, 3)
self.visualx = 1 if select_turn == 1 then
self.jump_timer = 0 self.turn = "left"
self.turn_timer = 0 elseif select_turn == 2 then
self.turn_speed = 0 self.turn = "right"
self.powered = false elseif select_turn == 3 then
self.knockback = false self.turn = "straight"
self.state = math.random(1,2) end
self.old_y = self.object:getpos().y self.turn_timer = 0
self.turn_speed = 0.05*math.random()
local data = minetest.deserialize(staticdata) end
if data and type(data) == "table" then end
if data.powered == true then
self.powered = true local def = {
self.object:set_properties({textures = {"creeper_powered.png"}}) hp_max = 20,
end physical = true,
else collisionbox = {-0.25, -0.7, -0.25, 0.25, 0.8, 0.25},
if math.random(0,20) == 20 then visual = "mesh",
self.powered = true mesh = "character.b3d",
self.object:set_properties({textures = {"creeper_powered.png"}}) textures = {"sneeker.png"},
end makes_footstep_sound = false,
end
end -- Original
animation = {
def.on_step = function(self, dtime) stand_START = 0,
if self.knockback then stand_END = 79,
return walk_START = 168,
end walk_END = 187
},
local ANIM_STAND = 1 walk_speed = 1.5,
local ANIM_WALK = 2 jump_height = 5,
animation_speed = 30,
local pos = self.object:getpos() knockback_level = 2
local yaw = self.object:getyaw() }
local inside = minetest.get_objects_inside_radius(pos,10) ]]
local walk_speed = self.walk_speed
local animation = self.animation local sneeker_on_activate = function(self, staticdata)
local anim_speed = self.animation_speed --[[
local velocity = self.object:getvelocity() self.yaw = 0
self.anim = 1
self.timer = self.timer+0.01 ]]
self.turn_timer = self.turn_timer+0.01 self.timer = 0
self.jump_timer = self.jump_timer+0.01 self.visualx = 1
--[[
if not self.chase self.jump_timer = 0
and self.timer > math.random(2,5) then self.turn_timer = 0
if math.random() > 0.8 then self.turn_speed = 0
self.state = "stand" ]]
else self.powered = false
self.state = "walk" --[[
end self.knockback = false
self.timer = 0 self.state = math.random(1, 2)
end self.old_y = self.object:get_pos().y
]]
if self.turn == "right" then
self.yaw = self.yaw+self.turn_speed local data = core.deserialize(staticdata)
self.object:setyaw(self.yaw) if data and type(data) == "table" then
elseif self.turn == "left" then if data.powered == true then
self.yaw = self.yaw-self.turn_speed self.powered = true
self.object:setyaw(self.yaw) self.object:set_properties({textures = {"sneeker_powered.png"}})
end end
else
if self.chase and self.visualx < 2 then if math.random(0, 20) == 20 then
if self.hiss == false then self.powered = true
minetest.sound_play("creeper_hiss",{pos=pos,gain=1.5,max_hear_distance=2*64}) self.object:set_properties({textures = {"sneeker_powered.png"}})
end end
self.visualx = self.visualx+0.05 end
self.object:set_properties({ end
visual_size = {x=self.visualx,y=1}
}) local function isnan(n)
self.hiss = true return tostring(n) == tostring((-1)^.5)
elseif self.visualx > 1 then end
self.visualx = self.visualx-0.05
self.object:set_properties({ local sneeker_on_step = function(self, dtime)
visual_size = {x=self.visualx,y=1} if self.stunned then return false end
})
self.hiss = false local pos = self.object:get_pos()
end local inside = core.get_objects_inside_radius(pos, 10)
local velocity = self.object:get_velocity()
self.chase = false
self.timer = self.timer+0.01
for _,object in ipairs(inside) do
if object:is_player() then if self.mode == "follow" and self.visualx < 2 then
self.state = "chase" if not self.hiss then
end core.sound_play("sneeker_hiss", {pos=pos, gain=1.5, max_hear_distance=2*64})
end end
self.visualx = self.visualx+0.05
if self.state == "stand" then self.object:set_properties({
if self.anim ~= ANIM_STAND then visual_size = {x=self.visualx, y=1}
self.object:set_animation({x=animation.stand_START,y=animation.stand_END},anim_speed,0) })
self.anim = ANIM_STAND self.hiss = true
end elseif self.visualx > 1 then
self.visualx = self.visualx-0.05
random_turn(self) self.object:set_properties({
visual_size = {x=self.visualx, y=1}
if velocity.x ~= 0 })
or velocity.z ~= 0 then self.hiss = false
self.object:setvelocity({x=0,y=velocity.y,z=0}) end
end
end for _, object in ipairs(inside) do
if object:is_player() then
if self.state == "walk" then self.mode = "follow"
if self.anim ~= ANIM_WALK then end
self.object:set_animation({x=animation.walk_START,y=animation.walk_END},anim_speed,0) end
self.anim = ANIM_WALK
end if self.mode == "follow" then
local inside_2 = core.get_objects_inside_radius(pos, 2)
self.direction = {x=math.sin(yaw)*-1,y=-10,z=math.cos(yaw)}
if self.direction then -- boom
self.object:setvelocity({x=self.direction.x*walk_speed,y=velocity.y,z=self.direction.z*walk_speed}) if #inside_2 ~= 0 then
end for _, object in ipairs(inside_2) do
if object:is_player() and object:get_hp() ~= 0 then
random_turn(self) if self.visualx >= 2 then
self.object:remove()
local velocity = self.object:getvelocity() sneeker.boom(pos, self.powered)
core.sound_play("sneeker_explode", {pos=pos, gain=1.5, max_hear_distance=2*64})
if self.turn_timer > 1 then return true
local direction = self.direction end
local npos = {x=pos.x+direction.x,y=pos.y+0.2,z=pos.z+direction.z} end
if velocity.x == 0 or velocity.z == 0 end
or minetest.registered_nodes[minetest.get_node(npos).name].walkable then end
local select_turn = math.random(1,2)
if select_turn == 1 then if #inside > 0 then
self.turn = "left" for _, object in ipairs(inside) do
elseif select_turn == 2 then if object:is_player() and object:get_hp() ~= 0 then
self.turn = "right" if #inside_2 > 0 then
end for _, object in ipairs(inside_2) do
self.turn_timer = 0 -- Stop move
self.turn_speed = 0.05*math.random() if object:is_player() then
end --[[
end if self.anim ~= ANIM_STAND then
self.object:set_animation({x=animation.stand_START, y=animation.stand_END}, anim_speed, 0)
-- Jump self.anim = ANIM_STAND
if self.jump_timer > 0.2 then end
jump(self,pos,self.direction) ]]
end --self.object:set_velocity({x=0, y=velocity.y, z=0})
end return false
end
if self.state == "chase" then end
if self.anim ~= ANIM_WALK then end
self.object:set_animation({x=animation.walk_START,y=animation.walk_END},anim_speed,0)
self.anim = ANIM_WALK -- follow player
end local ppos = object:get_pos()
self.vec = {x=ppos.x-pos.x, y=ppos.y-pos.y, z=ppos.z-pos.z}
self.turn = "straight" self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2
if ppos.x > pos.x then
local inside_2 = minetest.get_objects_inside_radius(pos,2) self.yaw = self.yaw+math.pi
end
-- Boom self.yaw = self.yaw-2
if #inside_2 ~= 0 then self.object:set_yaw(self.yaw)
for _,object in ipairs(inside_2) do self.direction = {x=math.sin(self.yaw)*-1, y=0, z=math.cos(self.yaw)}
if object:is_player() and object:get_hp() ~= 0 then
self.chase = true local direction = self.direction
if self.visualx >= 2 then local dir_x = direction.x*2.5
self.object:remove() local dir_y = velocity.y
creeper.boom(pos,self.powered) local dir_z = direction.z*2.5
minetest.sound_play("creeper_explode",{pos=pos,gain=1.5,max_hear_distance=2*64})
end if not isnan(dir_x) and not isnan(dir_y) and not isnan(dir_z) then
end self.object:set_velocity({x=direction.x*2.5, y=velocity.y, z=direction.z*2.5})
end else
end sneeker.log("warning", "Found NaN")
for k, v in ipairs({x=dir_x, y=dir_y, z=dir_z}) do
if #inside ~= 0 then if isnan(v) then
for _,object in ipairs(inside) do sneeker.log("warning", "\"" .. k .. "\" is not a number: " .. tostring(v))
if object:is_player() and object:get_hp() ~= 0 then end
if #inside_2 ~= 0 then end
for _,object in ipairs(inside_2) do end
-- Stop move end
if object:is_player() then end
if self.anim ~= ANIM_STAND then end
self.object:set_animation({x=animation.stand_START,y=animation.stand_END},anim_speed,0) end
self.anim = ANIM_STAND
end --[[
self.object:setvelocity({x=0,y=velocity.y,z=0}) if self.knockback then
return return
end end
end
end local ANIM_STAND = 1
local ANIM_WALK = 2
local ppos = object:getpos()
self.vec = {x=ppos.x-pos.x,y=ppos.y-pos.y,z=ppos.z-pos.z} local pos = self.object:get_pos()
self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2 local yaw = self.object:get_yaw()
if ppos.x > pos.x then local inside = core.get_objects_inside_radius(pos, 10)
self.yaw = self.yaw+math.pi local walk_speed = self.walk_speed
end local animation = self.animation
self.yaw = self.yaw-2 local anim_speed = self.animation_speed
self.object:setyaw(self.yaw) local velocity = self.object:get_velocity()
self.direction = {x=math.sin(self.yaw)*-1,y=0,z=math.cos(self.yaw)}
self.timer = self.timer+0.01
local direction = self.direction self.turn_timer = self.turn_timer+0.01
self.object:setvelocity({x=direction.x*2.5,y=velocity.y,z=direction.z*2.5}) self.jump_timer = self.jump_timer+0.01
-- Jump if not self.chase
if self.jump_timer > 0.2 then and self.timer > math.random(2, 5) then
jump(self,pos,direction) if math.random() > 0.8 then
end self.state = "stand"
end else
end self.state = "walk"
else end
self.state = "stand" self.timer = 0
end end
end
if self.turn == "right" then
-- Swim self.yaw = self.yaw+self.turn_speed
local node = minetest.get_node(pos) self.object:set_yaw(self.yaw)
if minetest.get_item_group(node.name,"water") ~= 0 then elseif self.turn == "left" then
self.object:setacceleration({x=0,y=1,z=0}) self.yaw = self.yaw-self.turn_speed
local velocity = self.object:getvelocity() self.object:set_yaw(self.yaw)
if self.object:getvelocity().y > 5 then end
self.object:setvelocity({x=0,y=velocity.y-velocity.y/2,z=0})
else if self.chase and self.visualx < 2 then
self.object:setvelocity({x=0,y=velocity.y+1,z=0}) if self.hiss == false then
end core.sound_play("sneeker_hiss", {pos=pos, gain=1.5, max_hear_distance=2*64})
else end
self.object:setacceleration({x=0,y=-10,z=0}) self.visualx = self.visualx+0.05
end self.object:set_properties({
end visual_size = {x=self.visualx, y=1}
})
def.on_punch = function(self,puncher,time_from_last_punch,tool_capabilities,dir) self.hiss = true
if self.knockback == false then elseif self.visualx > 1 then
local knockback_level = self.knockback_level self.visualx = self.visualx-0.05
self.object:setvelocity({x=dir.x*knockback_level,y=3,z=dir.z*knockback_level}) self.object:set_properties({
self.knockback = true visual_size = {x=self.visualx, y=1}
minetest.after(0.6,function() })
self.knockback = false self.hiss = false
end) end
end
if self.object:get_hp() < 1 then self.chase = false
local pos = self.object:getpos()
local x = 1/math.random(1,5)*dir.x for _, object in ipairs(inside) do
local z = 1/math.random(1,5)*dir.z if object:is_player() then
local p = {x=pos.x+x,y=pos.y,z=pos.z+z} self.state = "chase"
local node = minetest.get_node_or_nil(p) end
if node == nil or not node.name or node.name ~= "air" then end
p = pos
end if self.state == "stand" then
local obj = minetest.add_item(p, {name="tnt:gunpowder",count=math.random(0,2)}) if self.anim ~= ANIM_STAND then
end self.object:set_animation({x=animation.stand_START, y=animation.stand_END}, anim_speed, 0)
end self.anim = ANIM_STAND
end
def.get_staticdata = function(self)
return minetest.serialize({ random_turn(self)
powered = self.powered
}) if velocity.x ~= 0
end or velocity.z ~= 0 then
self.object:set_velocity({x=0, y=velocity.y, z=0})
minetest.register_entity("creeper:creeper",def) end
end
minetest.register_craftitem("creeper:spawnegg",{
description = "Creeper Spawn Egg", if self.state == "walk" then
inventory_image = "creeper_spawnegg.png", if self.anim ~= ANIM_WALK then
stack_max = 64, self.object:set_animation({x=animation.walk_START, y=animation.walk_END}, anim_speed, 0)
on_place = function(itemstack,placer,pointed_thing) self.anim = ANIM_WALK
if pointed_thing.type == "node" then end
local pos = pointed_thing.above
pos.y = pos.y+1 self.direction = {x=math.sin(yaw)*-1, y=-10, z=math.cos(yaw)}
minetest.add_entity(pos,"creeper:creeper") if self.direction then
if not minetest.setting_getbool("creative_mode") then self.object:set_velocity({x=self.direction.x*walk_speed, y=velocity.y, z=self.direction.z*walk_speed})
itemstack:take_item() end
end
return itemstack random_turn(self)
end
end local velocity = self.object:get_velocity()
})
if self.turn_timer > 1 then
local direction = self.direction
local npos = {x=pos.x+direction.x, y=pos.y+0.2, z=pos.z+direction.z}
if velocity.x == 0 or velocity.z == 0
or core.registered_nodes[core.get_node(npos).name].walkable then
local select_turn = math.random(1, 2)
if select_turn == 1 then
self.turn = "left"
elseif select_turn == 2 then
self.turn = "right"
end
self.turn_timer = 0
self.turn_speed = 0.05*math.random()
end
end
-- Jump
if self.jump_timer > 0.2 then
jump(self, pos, self.direction)
end
end
if self.state == "chase" then
if self.anim ~= ANIM_WALK then
self.object:set_animation({x=animation.walk_START, y=animation.walk_END}, anim_speed, 0)
self.anim = ANIM_WALK
end
self.turn = "straight"
local inside_2 = core.get_objects_inside_radius(pos, 2)
-- Boom
if #inside_2 ~= 0 then
for _, object in ipairs(inside_2) do
if object:is_player() and object:get_hp() ~= 0 then
self.chase = true
if self.visualx >= 2 then
self.object:remove()
sneeker.boom(pos, self.powered)
core.sound_play("sneeker_explode", {pos=pos, gain=1.5, max_hear_distance=2*64})
end
end
end
end
if #inside ~= 0 then
for _, object in ipairs(inside) do
if object:is_player() and object:get_hp() ~= 0 then
if #inside_2 ~= 0 then
for _, object in ipairs(inside_2) do
-- Stop move
if object:is_player() then
if self.anim ~= ANIM_STAND then
self.object:set_animation({x=animation.stand_START, y=animation.stand_END}, anim_speed, 0)
self.anim = ANIM_STAND
end
self.object:set_velocity({x=0, y=velocity.y, z=0})
return
end
end
end
local ppos = object:get_pos()
self.vec = {x=ppos.x-pos.x, y=ppos.y-pos.y, z=ppos.z-pos.z}
self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2
if ppos.x > pos.x then
self.yaw = self.yaw+math.pi
end
self.yaw = self.yaw-2
self.object:set_yaw(self.yaw)
self.direction = {x=math.sin(self.yaw)*-1, y=0, z=math.cos(self.yaw)}
local direction = self.direction
self.object:set_velocity({x=direction.x*2.5, y=velocity.y, z=direction.z*2.5})
-- Jump
if self.jump_timer > 0.2 then
jump(self, pos, direction)
end
end
end
else
self.state = "stand"
end
end
-- Swim
local node = core.get_node(pos)
if core.get_item_group(node.name, "water") ~= 0 then
self.object:set_acceleration({x=0, y=1, z=0})
local velocity = self.object:get_velocity()
if self.object:get_velocity().y > 5 then
self.object:set_velocity({x=0, y=velocity.y-velocity.y/2, z=0})
else
self.object:set_velocity({x=0, y=velocity.y+1, z=0})
end
else
self.object:set_acceleration({x=0, y=-10, z=0})
end
]]
end
--[[
def.on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
if self.knockback == false then
local knockback_level = self.knockback_level
self.object:set_velocity({x=dir.x*knockback_level, y=3, z=dir.z*knockback_level})
self.knockback = true
core.after(0.6, function()
self.knockback = false
end)
end
if self.object:get_hp() < 1 then
local pos = self.object:get_pos()
local x = 1/math.random(1, 5)*dir.x
local z = 1/math.random(1, 5)*dir.z
local p = {x=pos.x+x, y=pos.y, z=pos.z+z}
local node = core.get_node_or_nil(p)
if node == nil or not node.name or node.name ~= "air" then
p = pos
end
local obj = core.add_item(p, {name="tnt:gunpowder", count=math.random(0, 2)})
end
end
]]
local sneeker_get_staticdata = function(self)
return core.serialize({
powered = self.powered
})
end
--core.register_entity(sneeker.mob_name, def)
local spawn_nodes = {
"default:dirt",
"default:dirt_with_grass",
"default:dry_dirt_with_dry_grass",
"default:desert_sand",
"default:sand",
"default:stone",
"default:desert_stone",
}
if core.global_exists("nether") then
table.insert(spawn_nodes, "nether:rack")
end
local drops = nil
if core.global_exists("tnt") then
drops = {
{"tnt:gunpowder", {min=1, max=2}, chance=0.66},
}
end
cmer.register_mob({
name = sneeker.mob_name,
stats = {
hp = 20,
lifetime = 15 * 60, -- 15 minutes
can_jump = 5,
has_kockback = true,
sneaky = true,
},
modes = {
idle = {chance=0.3, moving_speed=0,},
walk = {chance=0.7, moving_speed=1.5,},
follow = {chance=0.0, moving_speed=1.5,},
inflate = {chance=0.0, moving_speed=0,},
},
model = {
mesh = "character.b3d",
textures = {"sneeker.png"},
collisionbox = {-0.25, -0.7, -0.25, 0.25, 0.8, 0.25},
rotation = 270.0,
animations = {
idle = {start=0, stop=79, speed=30,},
walk = {start=168, stop=187, speed=30,},
follow = {start=168, stop=187, speed=30,},
inflate = {start=0, stop=79, speed=30,},
},
},
sounds = {},
drops = drops,
spawning = {
abm_nodes = {
spawn_on = spawn_nodes,
},
abm_interval = sneeker.spawn_interval,
abm_chance = sneeker.spawn_chance,
max_number = 1,
number = 1,
time_range = {min=0, max=23999},
light = {min=sneeker.spawn_minlight, max=sneeker.spawn_maxlight},
height_limit = {min=sneeker.spawn_minheight, max=sneeker.spawn_maxheight},
},
on_step = sneeker_on_step,
on_activate = sneeker_on_activate,
get_staticdata = sneeker_get_staticdata,
})
if core.global_exists("asm") then
asm.addEgg({
name = "sneeker",
inventory_image = "sneeker_spawnegg.png",
spawn = "sneeker:sneeker",
})
core.register_alias(old_spawnegg_name, "spawneggs:sneeker")
if core.registered_items["tnt:tnt"] then
asm.addEggRecipe("sneeker", "tnt:tnt")
end
end

6
mod.conf Normal file
View File

@@ -0,0 +1,6 @@
name = sneeker
title = Sneeker
description = An explosive nuisance.
author = Rui
depends = cmer, default, tnt
optional_depends = asm_spawneggs, nether

53
settings.lua Normal file
View File

@@ -0,0 +1,53 @@
-- Settings for sneeker mod
sneeker.time_min = 60
sneeker.debug = core.settings:get_bool("enable_debug_mods", false)
--- Sets maximum number of spawns that can exist in world at one time.
--
-- @setting sneeker.spawn_cap
sneeker.spawn_cap = tonumber(core.settings:get("sneeker.spawn_cap")) or 10
--- Sets possibility for spawn.
--
-- Inverted value (e.g. 10000 = 1/10000).
--
-- @setting sneeker.spawn_chance
sneeker.spawn_chance = tonumber(core.settings:get("sneeker.spawn_chance")) or 10000
--- Sets frequency of spawn chance.
--
-- Default 240 is equivalent to 4 minutes (60 * 4).
--
-- @setting sneeker.spawn_interval
sneeker.spawn_interval = tonumber(core.settings:get("sneeker.spawn_interval")) or sneeker.time_min * 4
--- Sets the minimum light that a node must have for spawn to occur.
--
-- Default: 0
--
-- @setting sneeker.spawn_minlight
sneeker.spawn_minlight = tonumber(core.settings:get("sneeker.spawn_minlight")) or 0
--- Sets the maximum light that a node can have for spawn to occur.
--
-- Default: 9
--
-- @setting sneeker.spawn_maxlight
sneeker.spawn_maxlight = tonumber(core.settings:get("sneeker.spawn_maxlight")) or 9
--- Sets the lowest position at which sneeker can spawn.
--
-- Default: -31000
--
-- @setting sneeker.spawn_minheight
sneeker.spawn_minheight = tonumber(core.settings:get("sneeker.spawn_minheight")) or -31000
--- Sets the highest position at which sneeker can spawn.
--
-- Default: 31000
--
-- @setting sneeker.spawn_maxheight
sneeker.spawn_maxheight = tonumber(core.settings:get("sneeker.spawn_maxheight")) or 31000

23
settingtypes.txt Normal file
View File

@@ -0,0 +1,23 @@
# Sets maximum number of spawns that can exist in world.
sneeker.spawn_cap (Sneeker maximum spawns) int 10
# Sets possibility for spawn.
sneeker.spawn_chance (Sneeker spawn chance) int 10000
# Sets frequency of spawn chance. Default 240 is equivalent to 4 minutes (60 * 4).
sneeker.spawn_interval (Sneeker spawn interval) int 240
# Sets the minimum light that a node must have for spawn to occur.
sneeker.spawn_minlight (Sneeker min light for spawn) int 0
# Sets the maximum light that a node can have for spawn to occur.
sneeker.spawn_maxlight (Sneeker max light for spawn) int 9
# Sets the lowest position at which sneeker can spawn.
sneeker.spawn_minheight (Sneeker min spawn height) int -31000
# Sets the highest position at which sneeker can spawn.
sneeker.spawn_maxheight (Sneeker max spawn height) int 31000
# Logs extra debug messages.
enable_debug_mods (Enable debugging messages) bool false

View File

@@ -1,32 +1,84 @@
minetest.register_abm({
nodenames = {"default:dirt_with_grass","default:stone"}, local time_hr = sneeker.time_min * 60
local time_day = time_hr * 24
-- Display spawn chance as percentage in log
local spawn_chance_percent = math.floor(1 / sneeker.spawn_chance * 100)
if spawn_chance_percent < 1 then
spawn_chance_percent = "Less than 1%"
else
spawn_chance_percent = tostring(spawn_chance_percent) .. "%"
end
sneeker.log("Spawn cap: " .. tostring(sneeker.spawn_cap))
sneeker.log("Spawn chance: " .. spawn_chance_percent)
sneeker.log("Spawn interval: " .. tostring(sneeker.spawn_interval) .. " (" .. tostring(sneeker.spawn_interval/60) .. " minute(s))")
sneeker.log("Maximum light value for spawn: " .. tostring(sneeker.spawn_maxlight))
local spawn_nodes = {"default:dirt_with_grass", "default:stone"}
if core.global_exists("nether") then
table.insert(spawn_nodes, "nether:rack")
end
core.register_abm({
nodenames = spawn_nodes,
neighbors = {"air"}, neighbors = {"air"},
interval = 30, interval = spawn_interval,
chance = 9000, chance = spawn_chance,
action = function(pos, node, _, active_object_count_wider) action = function(pos, node, _, active_object_count_wider)
if active_object_count_wider > 5 then if active_object_count_wider > 5 then
return return
end end
-- Check light value of node
pos.y = pos.y+1 pos.y = pos.y+1
if not minetest.get_node_light(pos) then local node_light = core.get_node_light(pos)
-- Debugging spawning
sneeker.log("debug", "Node light level at " .. sneeker.get_pos_string(pos) .. ": " .. tostring(node_light))
-- Node light level
if not node_light or node_light > spawn_maxlight then
sneeker.log("debug", "Node not dark enough for spawn")
return
elseif node_light < spawn_minlight then
sneeker.log("debug", "Node too dark for spawn")
return return
end end
if minetest.get_node_light(pos) > 5 then
-- Spawn range
if spawn_minheight ~= nil and pos.y < spawn_minheight then
sneeker.log("debug", "Position is too low for spawn")
return
elseif pos.y > spawn_maxheight then
sneeker.log("debug", "Position is too high for spawn")
return return
end end
if minetest.get_node_light(pos) < -1 then
return -- Node must be touching air
end if core.get_node(pos).name ~= "air" then
if pos.y > 31000 then
return
end
if minetest.get_node(pos).name ~= "air" then
return return
end end
pos.y = pos.y+1 pos.y = pos.y+1
if minetest.get_node(pos).name ~= "air" then if core.get_node(pos).name ~= "air" then
return return
end end
minetest.add_entity(pos,"creeper:creeper")
-- Get total count of sneekers in world
local count = 0
for I in pairs(core.luaentities) do
if core.luaentities[I].name == sneeker.mob_name then
count = count + 1
end
end
sneeker.log("debug", "Current active spawns: " .. tostring(count) .. "/" .. tostring(spawn_cap))
if count >= spawn_cap then
sneeker.log("debug", "Max spawns reached")
return
end
sneeker.spawn(pos)
end end
}) })

View File

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 353 B

View File

Before

Width:  |  Height:  |  Size: 355 B

After

Width:  |  Height:  |  Size: 355 B

View File

Before

Width:  |  Height:  |  Size: 139 B

After

Width:  |  Height:  |  Size: 139 B

View File

Before

Width:  |  Height:  |  Size: 249 B

After

Width:  |  Height:  |  Size: 249 B

View File

@@ -1,14 +1,15 @@
-- From TNT -- From TNT
local cid_data = {} local cid_data = {}
local radius = tonumber(minetest.setting_get("tnt_radius") or 3) local radius = tonumber(core.settings:get("tnt_radius") or 3)
local large_radius = 5 local large_radius = 5
local loss_prob = { local loss_prob = {
["default:cobble"] = 3, ["default:cobble"] = 3,
["default:dirt"] = 4, ["default:dirt"] = 4,
} }
minetest.after(0, function() core.after(0, function()
for name, def in pairs(minetest.registered_nodes) do for name, def in pairs(core.registered_nodes) do
cid_data[minetest.get_content_id(name)] = { cid_data[core.get_content_id(name)] = {
name = name, name = name,
drops = def.drops, drops = def.drops,
flammable = def.groups.flammable, flammable = def.groups.flammable,
@@ -34,11 +35,11 @@ local function eject_drops(drops, pos, radius)
item:set_count(count) item:set_count(count)
end end
rand_pos(pos, drop_pos, radius) rand_pos(pos, drop_pos, radius)
local obj = minetest.add_item(drop_pos, item) local obj = core.add_item(drop_pos, item)
if obj then if obj then
obj:get_luaentity().collect = true obj:get_luaentity().collect = true
obj:setacceleration({x=0, y=-10, z=0}) obj:set_acceleration({x=0, y=-10, z=0})
obj:setvelocity({x=math.random(-3, 3), y=10, obj:set_velocity({x=math.random(-3, 3), y=10,
z=math.random(-3, 3)}) z=math.random(-3, 3)})
end end
count = count - max count = count - max
@@ -62,7 +63,7 @@ local function add_drop(drops, item)
end end
local function destroy(drops, pos, cid) local function destroy(drops, pos, cid)
if minetest.is_protected(pos, "") then if core.is_protected(pos, "") then
return return
end end
local def = cid_data[cid] local def = cid_data[cid]
@@ -70,9 +71,9 @@ local function destroy(drops, pos, cid)
def.on_blast(vector.new(pos), 1) def.on_blast(vector.new(pos), 1)
return return
end end
minetest.remove_node(pos) core.remove_node(pos)
if def then if def then
local node_drops = minetest.get_node_drops(def.name, "") local node_drops = core.get_node_drops(def.name, "")
for _, item in ipairs(node_drops) do for _, item in ipairs(node_drops) do
add_drop(drops, item) add_drop(drops, item)
end end
@@ -98,14 +99,14 @@ end
local function entity_physics(pos, radius) local function entity_physics(pos, radius)
-- Make the damage radius larger than the destruction radius -- Make the damage radius larger than the destruction radius
radius = radius * 2 radius = radius * 2
local objs = minetest.get_objects_inside_radius(pos, radius) local objs = core.get_objects_inside_radius(pos, radius)
for _, obj in pairs(objs) do for _, obj in pairs(objs) do
local obj_pos = obj:getpos() local obj_pos = obj:get_pos()
local obj_vel = obj:getvelocity() local obj_vel = obj:get_velocity()
local dist = math.max(1, vector.distance(pos, obj_pos)) local dist = math.max(1, vector.distance(pos, obj_pos))
if obj_vel ~= nil then if obj_vel ~= nil then
obj:setvelocity(calc_velocity(pos, obj_pos, obj:set_velocity(calc_velocity(pos, obj_pos,
obj_vel, radius * 10)) obj_vel, radius * 10))
end end
@@ -115,7 +116,7 @@ local function entity_physics(pos, radius)
end end
local function add_effects(pos, radius) local function add_effects(pos, radius)
minetest.add_particlespawner({ core.add_particlespawner({
amount = 128, amount = 128,
time = 1, time = 1,
minpos = vector.subtract(pos, radius / 2), minpos = vector.subtract(pos, radius / 2),
@@ -128,7 +129,7 @@ local function add_effects(pos, radius)
maxexptime = 3, maxexptime = 3,
minsize = 8, minsize = 8,
maxsize = 16, maxsize = 16,
texture = "creeper_smoke.png", texture = "sneeker_smoke.png",
}) })
end end
@@ -146,12 +147,16 @@ local function explode(pos, radius)
local drops = {} local drops = {}
local p = {} local p = {}
local c_air = minetest.get_content_id("air") local c_air = core.get_content_id("air")
local c_tnt = minetest.get_content_id("tnt:tnt") local c_tnt = nil
local c_tnt_burning = minetest.get_content_id("tnt:tnt_burning") if core.settings:get_bool("enable_tnt", false) then
local c_gunpowder = minetest.get_content_id("tnt:gunpowder") c_tnt = core.get_content_id("tnt:tnt")
local c_gunpowder_burning = minetest.get_content_id("tnt:gunpowder_burning") end
local c_boom = minetest.get_content_id("tnt:boom")
local c_tnt_burning = core.get_content_id("tnt:tnt_burning")
local c_gunpowder = core.get_content_id("tnt:gunpowder")
local c_gunpowder_burning = core.get_content_id("tnt:gunpowder_burning")
local c_boom = core.get_content_id("tnt:boom")
for z = -radius, radius do for z = -radius, radius do
for y = -radius, radius do for y = -radius, radius do
@@ -180,14 +185,14 @@ local function explode(pos, radius)
return drops return drops
end end
function creeper.boom(pos,large) function sneeker.boom(pos, large)
local radius = radius local radius = radius
if large then if large then
radius = large_radius radius = large_radius
end end
minetest.sound_play("creeper_explode", {pos=pos, gain=1.5, max_hear_distance=2*64}) core.sound_play("sneeker_explode", {pos=pos, gain=1.5, max_hear_distance=2*64})
minetest.set_node(pos, {name="tnt:boom"}) core.set_node(pos, {name="tnt:boom"})
minetest.get_node_timer(pos):start(0.5) core.get_node_timer(pos):start(0.5)
local drops = explode(pos, radius) local drops = explode(pos, radius)
entity_physics(pos, radius) entity_physics(pos, radius)
eject_drops(drops, pos, radius) eject_drops(drops, pos, radius)