123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- local c_air = minetest.get_content_id("air")
- defense_mob_api.register_mob("mob_sarangay:sarangay", {
- hp_max = 30,
- collisionbox = {-0.9,-0.01,-0.9, 0.9,2.5,0.9},
- mesh = "mob_sarangay_sarangay.b3d",
- textures = {"mob_sarangay_sarangay.png"},
- makes_footstep_sound = true,
- animation = {},
- normal_animation = {
- idle = {a=0, b=19, rate=10},
- jump = {a=60, b=69, rate=15},
- fall = {a=70, b=89, rate=20},
- attack = {a=40, b=59, rate=15},
- move = {a=20, b=39, rate=20},
- move_attack = {a=40, b=50, rate=15},
- },
- charging_animation = {
- idle = {a=120, b=129, rate=10},
- jump = {a=90, b=109, rate=10},
- fall = {a=90, b=109, rate=10},
- attack = {a=40, b=59, rate=15},
- move = {a=90, b=109, rate=30},
- move_attack = {a=40, b=50, rate=15},
- start = {a=110, b=119, rate=15},
- },
- smart_path = true,
- mass = 12,
- move_speed = 6,
- jump_height = 1,
- armor = 0,
- attack_damage = 4,
- attack_range = 2.0,
- attack_interval = 1.0,
- step_height = 1.3,
- charging = false,
- charge_power = 0,
- charge_destination = nil,
- charge_cooldown = 0,
- charge_timer = 0,
- idle_sound_cd = 5,
- on_activate = function(self, staticdata)
- self:set_charging_state(self.charging)
- defense_mob_api.default_prototype.on_activate(self, staticdata)
- end,
- on_step = function(self, dtime)
- defense_mob_api.default_prototype.on_step(self, dtime)
- local pos = self.object:get_pos()
- if self.charging
- then
- self.charge_timer = self.charge_timer + 1
- if self.charge_timer > 200
- then
- self:set_charging_state(false)
- end
- self.destination = self.charge_destination
- local pos = self.object:get_pos()
- pos.y = pos.y + 1.5
- local dir = self.object:getvelocity()
- dir.y = 0
- dir = vector.multiply(vector.normalize(dir), 2)
- local front_pos = vector.add(pos, dir)
- self:crash_blocks(front_pos, 3)
- self:crash_entities(pos, 3, 10)--front
- else
- local nearest = self:find_target()
- if nearest
- then
- if nearest.distance > 4 and
- self.charge_cooldown < 1 and
- math.abs(nearest.position.y - pos.y) < 4 and
- math.random() < 0.1
- then
- self:set_charging_state(true)
- elseif nearest.distance < 4
- then
- self.charge_cooldown = 5
- self:hunt()
- else
- self.charge_cooldown = self.charge_cooldown - 1
- local dir = vector.aim(nearest.position, pos)
- self.destination = vector.add(nearest.position, vector.multiply(dir, 12))
- end
- end
- end
- end,
- set_charging_state = function(self, state)
- self.charging = state
- if state
- then
- self.move_speed = 9
- self.animation = self.charging_animation
- self:set_animation("charge")
- self:charge()
- self.destination = nil
- self.charge_timer = 0
- self:make_sound("charge", false, 2, 0.5 + (math.random() - 0.5) / 4, 32)
- else
- self.move_speed = 6
- self.animation = self.normal_animation
- self:set_animation("attack")
- self.charge_cooldown = 100
- self.charge_destination = nil
- end
- end,
- crash_blocks = function(self, pos, radius)
- local p = {x=0, y=0, z=pos.z - radius}
- for z = -radius, radius
- do
- p.y = pos.y - radius
- for y = -radius, radius
- do
- p.x = pos.x - radius
- for x = -radius, radius
- do
- if x*x + y*y + z*z <= radius
- then
- local node = minetest.get_node_or_nil(p)
- if node
- then
- local did_something = false
- local result = erosion.get_erosion_result(node.name, 4)
- if node.name ~= result
- then
- did_something = true
- minetest.set_node(p, {name = result})
- end
- if (minetest.registered_nodes[node.name] or {groups = {}}).groups.crumbly
- then
- did_something = true
- minetest.spawn_falling_node(p)
- end
- if did_something and math.random() < 0.1
- then
- self.charge_timer = 200 --stop charging prematurely
- end
- end
- end
- p.x = p.x + 1
- end
- p.y = p.y + 1
- end
- p.z = p.z + 1
- end
- end,
- crash_entities = function(self, pos, radius, maxweight)
- local v = self.object:getvelocity()
- for _,o in ipairs(minetest.get_objects_inside_radius(pos, radius))
- do
- if o ~= self.object
- then
- o:punch(self.object, 1.0, {
- full_punch_interval=1.0,
- damage_groups = {fleshy=1}
- }, nil)
- if math.random() < 0.01
- then
- self.charge_timer = 200 --stop charging prematurely
- end
- local e = o:get_luaentity()
- if e
- then
- o:setvelocity({x = 0, y = 3 + math.random() * vector.length(v), z = 0})
- end
- end
- end
- return maxweight
- end,
- charge = function(self)
- local nearest = self:find_target()
- if nearest.player
- then
- local pos = self.object:get_pos()
- local r = math.max(0, self.attack_range - 2)
- local dir = vector.aim(nearest.position, pos)
- self.destination = vector.add(nearest.position, vector.multiply(dir, nearest.distance * -1.3))
- self.charge_destination = self.destination
- end
- end,
- })
- minetest.register_alias("sarangay", "mob_sarangay:sarangay")
|