[Mod] Simple Mobs [mobs]

User avatar
PilzAdam
Member
 
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam

by PilzAdam » Mon Feb 04, 2013 14:29

socramazibi wrote:Hello, I have searched other sound of the sheep, I think this sounds better. In case anyone is interested.

greetings

Download

What license?
 

User avatar
jojoa1997
Member
 
Posts: 2890
Joined: Thu Dec 13, 2012 05:11

by jojoa1997 » Mon Feb 04, 2013 14:39

could you make an option to have 3d mods?
Coding;
1X coding
3X debugging
12X tweaking to be just right
 

socramazibi
Member
 
Posts: 81
Joined: Mon Jan 28, 2013 12:29

by socramazibi » Mon Feb 04, 2013 15:25

PilzAdam wrote:
socramazibi wrote:Hello, I have searched other sound of the sheep, I think this sounds better. In case anyone is interested.

greetings

Download

What license?


The license? Because I found the sound on this website web and I then cut it to occupy less and pass ogg.

greetings
Forgive my English, but it is the translator of google.My Spanish.
My mod:
Pictures wool 1.0 3x5 , Charcoal+Textures , Map
 

User avatar
LorenzoVulcan
Member
 
Posts: 437
Joined: Mon Mar 12, 2012 06:46

by LorenzoVulcan » Mon Feb 04, 2013 17:26

jojoa1997 wrote:could you make an option to have 3d mods?

That's an experimental fork i made for 3d mobs.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
---3d Monsters

function mobs:register_mob_3d(name, def)
    minetest.register_entity(name, {
        hp_max = def.hp_max,
        physical = true,
        collisionbox = def.collisionbox,
        visual = def.visual,
        visual_size = def.visual_size,
        mesh=def.mesh,
        textures = def.textures,
        makes_footstep_sound = def.makes_footstep_sound,
        view_range = def.view_range,
        walk_velocity = def.walk_velocity,
        run_velocity = def.run_velocity,
        damage = def.damage,
        light_damage = def.light_damage,
        water_damage = def.water_damage,
        lava_damage = def.lava_damage,
        drops = def.drops,
        armor = def.armor,
        drawtype = def.drawtype,
        on_rightclick = def.on_rightclick,
        type = def.type,
        attack_type = def.attack_type,
        arrow = def.arrow,
        shoot_interval = def.shoot_interval,
        sounds = def.sounds,
       
        timer = 0,
        attack = {player=nil, dist=nil},
        state = "stand",
        v_start = false,
        old_y = nil,
       
       
        set_velocity = function(self, v)
            local yaw = self.object:getyaw()
            if self.drawtype == "side" then
                yaw = yaw+(math.pi/2)
            end
            local x = math.sin(yaw) * -v
            local z = math.cos(yaw) * v
            self.object:setvelocity({x=x, y=self.object:getvelocity().y, z=z})
        end,
       
        get_velocity = function(self)
            local v = self.object:getvelocity()
            return (v.x^2 + v.z^2)^(0.5)
        end,
       
        on_step = function(self, dtime)
            if self.type == "monster" and minetest.setting_getbool("only_peaceful_mobs") then
                self.object:remove()
            end
           
            if self.object:getvelocity().y > 0.1 then
                local yaw = self.object:getyaw()
                if self.drawtype == "side" then
                    yaw = yaw+(math.pi/2)
                end
                local x = math.sin(yaw) * -2
                local z = math.cos(yaw) * 2
                self.object:setacceleration({x=x, y=-10, z=z})
            else
                self.object:setacceleration({x=0, y=-10, z=0})
            end
           
            if self.object:getvelocity().y == 0 then
                if not self.old_y then
                    self.old_y = self.object:getpos().y
                else
                    local d = self.old_y - self.object:getpos().y
                    if d > 5 then
                        local damage = d-5
                        self.object:punch(self.object, 1.0, {
                            full_punch_interval=1.0,
                            groupcaps={
                                fleshy={times={[self.armor]=1/damage}},
                            }
                        }, nil)
                    end
                    self.old_y = self.object:getpos().y
                end
            end
           
            self.timer = self.timer+dtime
            if self.state ~= "attack" then
                if self.timer < 1 then
                    return
                end
                self.timer = 0
            end
           
            if self.sounds and self.sounds.random and math.random(1, 100) <= 1 then
                minetest.sound_play(self.sounds.random, {object = self.object})
            end
           
            local do_env_damage = function(self)
                if self.light_damage and self.light_damage ~= 0 and self.object:getpos().y>0 and minetest.env:get_node_light(self.object:getpos()) and minetest.env:get_node_light(self.object:getpos()) > 3 and minetest.env:get_timeofday() > 0.2 and minetest.env:get_timeofday() < 0.8 then
                    self.object:punch(self.object, 1.0, {
                        full_punch_interval=1.0,
                        groupcaps={
                            fleshy={times={[self.armor]=1/self.light_damage}},
                        }
                    }, nil)
                end
               
                if self.water_damage and self.water_damage ~= 0 and string.find(minetest.env:get_node(self.object:getpos()).name, "default:water") then
                    self.object:punch(self.object, 1.0, {
                        full_punch_interval=1.0,
                        groupcaps={
                            fleshy={times={[self.armor]=1/self.water_damage}},
                        }
                    }, nil)
                end
               
                if self.lava_damage and self.lava_damage ~= 0 and string.find(minetest.env:get_node(self.object:getpos()).name, "default:lava") then
                    self.object:punch(self.object, 1.0, {
                        full_punch_interval=1.0,
                        groupcaps={
                            fleshy={times={[self.armor]=1/self.lava_damage}},
                        }
                    }, nil)
                end
            end
           
            if self.state == "attack" and self.timer > 1 then
                do_env_damage(self)
            elseif self.state ~= "attack" then
                do_env_damage(self)
            end
           
            if self.type == "monster" then
                for _,player in pairs(minetest.get_connected_players()) do
                    local s = self.object:getpos()
                    local p = player:getpos()
                    local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
                    if dist < self.view_range then
                        if self.attack.dist then
                            if self.attack.dist < dist then
                                self.state = "attack"
                                self.attack.player = player
                                self.attack.dist = dist
                            end
                        else
                            self.state = "attack"
                            self.attack.player = player
                            self.attack.dist = dist
                        end
                    end
                end
            end
           
            if self.state == "stand" then
                if math.random(1, 2) == 1 then
                    self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
                end
                if math.random(1, 100) <= 50 then
                    self.set_velocity(self, self.walk_velocity)
                    self.state = "walk"
                end
            elseif self.state == "walk" then
                if math.random(1, 100) <= 30 then
                    self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
                    self.set_velocity(self, self.get_velocity(self))
                end
                if math.random(1, 100) <= 10 then
                    self.set_velocity(self, 0)
                    self.state = "stand"
                end
                if self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
                    local v = self.object:getvelocity()
                    v.y = 5
                    self.object:setvelocity(v)
                end
            elseif self.state == "attack" and self.attack_type == "dogfight" then
                if not self.attack.player or not self.attack.player:is_player() then
                    self.state = "stand"
                    return
                end
                local s = self.object:getpos()
                local p = self.attack.player:getpos()
                local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
                if dist > self.view_range or self.attack.player:get_hp() <= 0 then
                    self.state = "stand"
                    self.v_start = false
                    self.set_velocity(self, 0)
                    self.attack = {player=nil, dist=nil}
                    return
                else
                    self.attack.dist = dist
                end
               
                local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z}
                local yaw = math.atan(vec.z/vec.x)+math.pi/2
                if self.drawtype == "side" then
                    yaw = yaw+(math.pi/2)
                end
                if p.x > s.x then
                    yaw = yaw+math.pi
                end
                self.object:setyaw(yaw)
                if self.attack.dist > 2 then
                    if not self.v_start then
                        self.v_start = true
                        self.set_velocity(self, self.run_velocity)
                    else
                        if self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
                            local v = self.object:getvelocity()
                            v.y = 5
                            self.object:setvelocity(v)
                        end
                        self.set_velocity(self, self.run_velocity)
                    end
                else
                    self.set_velocity(self, 0)
                    self.v_start = false
                    if self.timer > 1 then
                        self.timer = 0
                        local d1 = 10
                        local d2 = 10
                        local d3 = 10
                        if self.damage > 0 then
                            d3 = 1/self.damage
                        end
                        if self.damage > 1 then
                            d2 = 1/(self.damage-1)
                        end
                        if self.damage > 2 then
                            d1 = 1/(self.damage-2)
                        end
                        if self.sounds and self.sounds.attack then
                            minetest.sound_play(self.sounds.attack, {object = self.object})
                        end
                        self.attack.player:punch(self.object, 1.0,  {
                            full_punch_interval=1.0,
                            groupcaps={
                                fleshy={times={[1]=d1, [2]=d2, [3]=d3}},
                            }
                        }, vec)
                    end
                end
            elseif self.state == "attack" and self.attack_type == "shoot" then
                if not self.attack.player or not self.attack.player:is_player() then
                    self.state = "stand"
                    return
                end
                local s = self.object:getpos()
                local p = self.attack.player:getpos()
                local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
                if dist > self.view_range or self.attack.player:get_hp() <= 0 then
                    self.state = "stand"
                    self.v_start = false
                    self.set_velocity(self, 0)
                    self.attack = {player=nil, dist=nil}
                    return
                else
                    self.attack.dist = dist
                end
               
                local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z}
                local yaw = math.atan(vec.z/vec.x)+math.pi/2
                if self.drawtype == "side" then
                    yaw = yaw+(math.pi/2)
                end
                if p.x > s.x then
                    yaw = yaw+math.pi
                end
                self.object:setyaw(yaw)
                self.set_velocity(self, 0)
               
                if self.timer > self.shoot_interval and math.random(1, 100) <= 60 then
                    self.timer = 0
                   
                    if self.sounds and self.sounds.attack then
                        minetest.sound_play(self.sounds.attack, {object = self.object})
                    end
                   
                    local obj = minetest.env:add_entity(self.object:getpos(), self.arrow)
                    local amount = (vec.x^2+vec.y^2+vec.z^2)^0.5
                    local v = obj:get_luaentity().velocity
                    vec.y = vec.y+1
                    vec.x = vec.x*v/amount
                    vec.y = vec.y*v/amount
                    vec.z = vec.z*v/amount
                    obj:setvelocity(vec)
                end
            end
        end,
       
        on_activate = function(self, staticdata)
            self.object:set_armor_groups({fleshy=self.armor})
            self.object:setacceleration({x=0, y=-10, z=0})
            self.state = "stand"
            self.object:setvelocity({x=0, y=self.object:getvelocity().y, z=0})
            self.object:setyaw(math.random(1, 360)/180*math.pi)
            if self.type == "monster" and minetest.setting_getbool("only_peaceful_mobs") then
                self.object:remove()
            end
        end,
       
        on_punch = function(self, hitter)
            if self.object:get_hp() <= 0 then
                if hitter and hitter:is_player() and hitter:get_inventory() then
                    for _,drop in ipairs(self.drops) do
                        if math.random(1, drop.chance) == 1 then
                            minetest.env:add_item(self.object:getpos(), ItemStack(drop.name.." "..math.random(drop.min, drop.max)))
                        end
                    end
                else
                    for _,drop in ipairs(self.drops) do
                        if math.random(1, drop.chance) == 1 then
                            for i=1,math.random(drop.min, drop.max) do
                                local obj = minetest.env:add_item(self.object:getpos(), drop.name)
                                if obj then
                                    obj:get_luaentity().collect = true
                                    local x = math.random(1, 5)
                                    if math.random(1,2) == 1 then
                                        x = -x
                                    end
                                    local z = math.random(1, 5)
                                    if math.random(1,2) == 1 then
                                        z = -z
                                    end
                                    obj:setvelocity({x=1/x, y=obj:getvelocity().y, z=1/z})
                                end
                            end
                        end
                    end
                end
            end
        end,
       
    })
end
Developer of the BlockForge 2# Project!
Official thread: http://minetest.net/forum/viewtopic.php?pid=54290#p54290
 

User avatar
PilzAdam
Member
 
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam

by PilzAdam » Mon Feb 04, 2013 17:29

LorenzoVulcan wrote:
jojoa1997 wrote:could you make an option to have 3d mods?

That's an experimental fork i made for 3d mobs.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
---3d Monsters

function mobs:register_mob_3d(name, def)
    minetest.register_entity(name, {
        hp_max = def.hp_max,
        physical = true,
        collisionbox = def.collisionbox,
        visual = def.visual,
        visual_size = def.visual_size,
        mesh=def.mesh,
        textures = def.textures,
        makes_footstep_sound = def.makes_footstep_sound,
        view_range = def.view_range,
        walk_velocity = def.walk_velocity,
        run_velocity = def.run_velocity,
        damage = def.damage,
        light_damage = def.light_damage,
        water_damage = def.water_damage,
        lava_damage = def.lava_damage,
        drops = def.drops,
        armor = def.armor,
        drawtype = def.drawtype,
        on_rightclick = def.on_rightclick,
        type = def.type,
        attack_type = def.attack_type,
        arrow = def.arrow,
        shoot_interval = def.shoot_interval,
        sounds = def.sounds,
       
        timer = 0,
        attack = {player=nil, dist=nil},
        state = "stand",
        v_start = false,
        old_y = nil,
       
       
        set_velocity = function(self, v)
            local yaw = self.object:getyaw()
            if self.drawtype == "side" then
                yaw = yaw+(math.pi/2)
            end
            local x = math.sin(yaw) * -v
            local z = math.cos(yaw) * v
            self.object:setvelocity({x=x, y=self.object:getvelocity().y, z=z})
        end,
       
        get_velocity = function(self)
            local v = self.object:getvelocity()
            return (v.x^2 + v.z^2)^(0.5)
        end,
       
        on_step = function(self, dtime)
            if self.type == "monster" and minetest.setting_getbool("only_peaceful_mobs") then
                self.object:remove()
            end
           
            if self.object:getvelocity().y > 0.1 then
                local yaw = self.object:getyaw()
                if self.drawtype == "side" then
                    yaw = yaw+(math.pi/2)
                end
                local x = math.sin(yaw) * -2
                local z = math.cos(yaw) * 2
                self.object:setacceleration({x=x, y=-10, z=z})
            else
                self.object:setacceleration({x=0, y=-10, z=0})
            end
           
            if self.object:getvelocity().y == 0 then
                if not self.old_y then
                    self.old_y = self.object:getpos().y
                else
                    local d = self.old_y - self.object:getpos().y
                    if d > 5 then
                        local damage = d-5
                        self.object:punch(self.object, 1.0, {
                            full_punch_interval=1.0,
                            groupcaps={
                                fleshy={times={[self.armor]=1/damage}},
                            }
                        }, nil)
                    end
                    self.old_y = self.object:getpos().y
                end
            end
           
            self.timer = self.timer+dtime
            if self.state ~= "attack" then
                if self.timer < 1 then
                    return
                end
                self.timer = 0
            end
           
            if self.sounds and self.sounds.random and math.random(1, 100) <= 1 then
                minetest.sound_play(self.sounds.random, {object = self.object})
            end
           
            local do_env_damage = function(self)
                if self.light_damage and self.light_damage ~= 0 and self.object:getpos().y>0 and minetest.env:get_node_light(self.object:getpos()) and minetest.env:get_node_light(self.object:getpos()) > 3 and minetest.env:get_timeofday() > 0.2 and minetest.env:get_timeofday() < 0.8 then
                    self.object:punch(self.object, 1.0, {
                        full_punch_interval=1.0,
                        groupcaps={
                            fleshy={times={[self.armor]=1/self.light_damage}},
                        }
                    }, nil)
                end
               
                if self.water_damage and self.water_damage ~= 0 and string.find(minetest.env:get_node(self.object:getpos()).name, "default:water") then
                    self.object:punch(self.object, 1.0, {
                        full_punch_interval=1.0,
                        groupcaps={
                            fleshy={times={[self.armor]=1/self.water_damage}},
                        }
                    }, nil)
                end
               
                if self.lava_damage and self.lava_damage ~= 0 and string.find(minetest.env:get_node(self.object:getpos()).name, "default:lava") then
                    self.object:punch(self.object, 1.0, {
                        full_punch_interval=1.0,
                        groupcaps={
                            fleshy={times={[self.armor]=1/self.lava_damage}},
                        }
                    }, nil)
                end
            end
           
            if self.state == "attack" and self.timer > 1 then
                do_env_damage(self)
            elseif self.state ~= "attack" then
                do_env_damage(self)
            end
           
            if self.type == "monster" then
                for _,player in pairs(minetest.get_connected_players()) do
                    local s = self.object:getpos()
                    local p = player:getpos()
                    local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
                    if dist < self.view_range then
                        if self.attack.dist then
                            if self.attack.dist < dist then
                                self.state = "attack"
                                self.attack.player = player
                                self.attack.dist = dist
                            end
                        else
                            self.state = "attack"
                            self.attack.player = player
                            self.attack.dist = dist
                        end
                    end
                end
            end
           
            if self.state == "stand" then
                if math.random(1, 2) == 1 then
                    self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
                end
                if math.random(1, 100) <= 50 then
                    self.set_velocity(self, self.walk_velocity)
                    self.state = "walk"
                end
            elseif self.state == "walk" then
                if math.random(1, 100) <= 30 then
                    self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
                    self.set_velocity(self, self.get_velocity(self))
                end
                if math.random(1, 100) <= 10 then
                    self.set_velocity(self, 0)
                    self.state = "stand"
                end
                if self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
                    local v = self.object:getvelocity()
                    v.y = 5
                    self.object:setvelocity(v)
                end
            elseif self.state == "attack" and self.attack_type == "dogfight" then
                if not self.attack.player or not self.attack.player:is_player() then
                    self.state = "stand"
                    return
                end
                local s = self.object:getpos()
                local p = self.attack.player:getpos()
                local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
                if dist > self.view_range or self.attack.player:get_hp() <= 0 then
                    self.state = "stand"
                    self.v_start = false
                    self.set_velocity(self, 0)
                    self.attack = {player=nil, dist=nil}
                    return
                else
                    self.attack.dist = dist
                end
               
                local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z}
                local yaw = math.atan(vec.z/vec.x)+math.pi/2
                if self.drawtype == "side" then
                    yaw = yaw+(math.pi/2)
                end
                if p.x > s.x then
                    yaw = yaw+math.pi
                end
                self.object:setyaw(yaw)
                if self.attack.dist > 2 then
                    if not self.v_start then
                        self.v_start = true
                        self.set_velocity(self, self.run_velocity)
                    else
                        if self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
                            local v = self.object:getvelocity()
                            v.y = 5
                            self.object:setvelocity(v)
                        end
                        self.set_velocity(self, self.run_velocity)
                    end
                else
                    self.set_velocity(self, 0)
                    self.v_start = false
                    if self.timer > 1 then
                        self.timer = 0
                        local d1 = 10
                        local d2 = 10
                        local d3 = 10
                        if self.damage > 0 then
                            d3 = 1/self.damage
                        end
                        if self.damage > 1 then
                            d2 = 1/(self.damage-1)
                        end
                        if self.damage > 2 then
                            d1 = 1/(self.damage-2)
                        end
                        if self.sounds and self.sounds.attack then
                            minetest.sound_play(self.sounds.attack, {object = self.object})
                        end
                        self.attack.player:punch(self.object, 1.0,  {
                            full_punch_interval=1.0,
                            groupcaps={
                                fleshy={times={[1]=d1, [2]=d2, [3]=d3}},
                            }
                        }, vec)
                    end
                end
            elseif self.state == "attack" and self.attack_type == "shoot" then
                if not self.attack.player or not self.attack.player:is_player() then
                    self.state = "stand"
                    return
                end
                local s = self.object:getpos()
                local p = self.attack.player:getpos()
                local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
                if dist > self.view_range or self.attack.player:get_hp() <= 0 then
                    self.state = "stand"
                    self.v_start = false
                    self.set_velocity(self, 0)
                    self.attack = {player=nil, dist=nil}
                    return
                else
                    self.attack.dist = dist
                end
               
                local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z}
                local yaw = math.atan(vec.z/vec.x)+math.pi/2
                if self.drawtype == "side" then
                    yaw = yaw+(math.pi/2)
                end
                if p.x > s.x then
                    yaw = yaw+math.pi
                end
                self.object:setyaw(yaw)
                self.set_velocity(self, 0)
               
                if self.timer > self.shoot_interval and math.random(1, 100) <= 60 then
                    self.timer = 0
                   
                    if self.sounds and self.sounds.attack then
                        minetest.sound_play(self.sounds.attack, {object = self.object})
                    end
                   
                    local obj = minetest.env:add_entity(self.object:getpos(), self.arrow)
                    local amount = (vec.x^2+vec.y^2+vec.z^2)^0.5
                    local v = obj:get_luaentity().velocity
                    vec.y = vec.y+1
                    vec.x = vec.x*v/amount
                    vec.y = vec.y*v/amount
                    vec.z = vec.z*v/amount
                    obj:setvelocity(vec)
                end
            end
        end,
       
        on_activate = function(self, staticdata)
            self.object:set_armor_groups({fleshy=self.armor})
            self.object:setacceleration({x=0, y=-10, z=0})
            self.state = "stand"
            self.object:setvelocity({x=0, y=self.object:getvelocity().y, z=0})
            self.object:setyaw(math.random(1, 360)/180*math.pi)
            if self.type == "monster" and minetest.setting_getbool("only_peaceful_mobs") then
                self.object:remove()
            end
        end,
       
        on_punch = function(self, hitter)
            if self.object:get_hp() <= 0 then
                if hitter and hitter:is_player() and hitter:get_inventory() then
                    for _,drop in ipairs(self.drops) do
                        if math.random(1, drop.chance) == 1 then
                            minetest.env:add_item(self.object:getpos(), ItemStack(drop.name.." "..math.random(drop.min, drop.max)))
                        end
                    end
                else
                    for _,drop in ipairs(self.drops) do
                        if math.random(1, drop.chance) == 1 then
                            for i=1,math.random(drop.min, drop.max) do
                                local obj = minetest.env:add_item(self.object:getpos(), drop.name)
                                if obj then
                                    obj:get_luaentity().collect = true
                                    local x = math.random(1, 5)
                                    if math.random(1,2) == 1 then
                                        x = -x
                                    end
                                    local z = math.random(1, 5)
                                    if math.random(1,2) == 1 then
                                        z = -z
                                    end
                                    obj:setvelocity({x=1/x, y=obj:getvelocity().y, z=1/z})
                                end
                            end
                        end
                    end
                end
            end
        end,
       
    })
end

Nice :D
Can you create a diff against the current register_mobs function? It would make it easier to check the 3D parts.
 

User avatar
PilzAdam
Member
 
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam

by PilzAdam » Mon Feb 04, 2013 17:33

PilzAdam wrote:
LorenzoVulcan wrote:
jojoa1997 wrote:could you make an option to have 3d mods?

That's an experimental fork i made for 3d mobs.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
---3d Monsters

function mobs:register_mob_3d(name, def)
    minetest.register_entity(name, {
        hp_max = def.hp_max,
        physical = true,
        collisionbox = def.collisionbox,
        visual = def.visual,
        visual_size = def.visual_size,
        mesh=def.mesh,
        textures = def.textures,
        makes_footstep_sound = def.makes_footstep_sound,
        view_range = def.view_range,
        walk_velocity = def.walk_velocity,
        run_velocity = def.run_velocity,
        damage = def.damage,
        light_damage = def.light_damage,
        water_damage = def.water_damage,
        lava_damage = def.lava_damage,
        drops = def.drops,
        armor = def.armor,
        drawtype = def.drawtype,
        on_rightclick = def.on_rightclick,
        type = def.type,
        attack_type = def.attack_type,
        arrow = def.arrow,
        shoot_interval = def.shoot_interval,
        sounds = def.sounds,
       
        timer = 0,
        attack = {player=nil, dist=nil},
        state = "stand",
        v_start = false,
        old_y = nil,
       
       
        set_velocity = function(self, v)
            local yaw = self.object:getyaw()
            if self.drawtype == "side" then
                yaw = yaw+(math.pi/2)
            end
            local x = math.sin(yaw) * -v
            local z = math.cos(yaw) * v
            self.object:setvelocity({x=x, y=self.object:getvelocity().y, z=z})
        end,
       
        get_velocity = function(self)
            local v = self.object:getvelocity()
            return (v.x^2 + v.z^2)^(0.5)
        end,
       
        on_step = function(self, dtime)
            if self.type == "monster" and minetest.setting_getbool("only_peaceful_mobs") then
                self.object:remove()
            end
           
            if self.object:getvelocity().y > 0.1 then
                local yaw = self.object:getyaw()
                if self.drawtype == "side" then
                    yaw = yaw+(math.pi/2)
                end
                local x = math.sin(yaw) * -2
                local z = math.cos(yaw) * 2
                self.object:setacceleration({x=x, y=-10, z=z})
            else
                self.object:setacceleration({x=0, y=-10, z=0})
            end
           
            if self.object:getvelocity().y == 0 then
                if not self.old_y then
                    self.old_y = self.object:getpos().y
                else
                    local d = self.old_y - self.object:getpos().y
                    if d > 5 then
                        local damage = d-5
                        self.object:punch(self.object, 1.0, {
                            full_punch_interval=1.0,
                            groupcaps={
                                fleshy={times={[self.armor]=1/damage}},
                            }
                        }, nil)
                    end
                    self.old_y = self.object:getpos().y
                end
            end
           
            self.timer = self.timer+dtime
            if self.state ~= "attack" then
                if self.timer < 1 then
                    return
                end
                self.timer = 0
            end
           
            if self.sounds and self.sounds.random and math.random(1, 100) <= 1 then
                minetest.sound_play(self.sounds.random, {object = self.object})
            end
           
            local do_env_damage = function(self)
                if self.light_damage and self.light_damage ~= 0 and self.object:getpos().y>0 and minetest.env:get_node_light(self.object:getpos()) and minetest.env:get_node_light(self.object:getpos()) > 3 and minetest.env:get_timeofday() > 0.2 and minetest.env:get_timeofday() < 0.8 then
                    self.object:punch(self.object, 1.0, {
                        full_punch_interval=1.0,
                        groupcaps={
                            fleshy={times={[self.armor]=1/self.light_damage}},
                        }
                    }, nil)
                end
               
                if self.water_damage and self.water_damage ~= 0 and string.find(minetest.env:get_node(self.object:getpos()).name, "default:water") then
                    self.object:punch(self.object, 1.0, {
                        full_punch_interval=1.0,
                        groupcaps={
                            fleshy={times={[self.armor]=1/self.water_damage}},
                        }
                    }, nil)
                end
               
                if self.lava_damage and self.lava_damage ~= 0 and string.find(minetest.env:get_node(self.object:getpos()).name, "default:lava") then
                    self.object:punch(self.object, 1.0, {
                        full_punch_interval=1.0,
                        groupcaps={
                            fleshy={times={[self.armor]=1/self.lava_damage}},
                        }
                    }, nil)
                end
            end
           
            if self.state == "attack" and self.timer > 1 then
                do_env_damage(self)
            elseif self.state ~= "attack" then
                do_env_damage(self)
            end
           
            if self.type == "monster" then
                for _,player in pairs(minetest.get_connected_players()) do
                    local s = self.object:getpos()
                    local p = player:getpos()
                    local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
                    if dist < self.view_range then
                        if self.attack.dist then
                            if self.attack.dist < dist then
                                self.state = "attack"
                                self.attack.player = player
                                self.attack.dist = dist
                            end
                        else
                            self.state = "attack"
                            self.attack.player = player
                            self.attack.dist = dist
                        end
                    end
                end
            end
           
            if self.state == "stand" then
                if math.random(1, 2) == 1 then
                    self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
                end
                if math.random(1, 100) <= 50 then
                    self.set_velocity(self, self.walk_velocity)
                    self.state = "walk"
                end
            elseif self.state == "walk" then
                if math.random(1, 100) <= 30 then
                    self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
                    self.set_velocity(self, self.get_velocity(self))
                end
                if math.random(1, 100) <= 10 then
                    self.set_velocity(self, 0)
                    self.state = "stand"
                end
                if self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
                    local v = self.object:getvelocity()
                    v.y = 5
                    self.object:setvelocity(v)
                end
            elseif self.state == "attack" and self.attack_type == "dogfight" then
                if not self.attack.player or not self.attack.player:is_player() then
                    self.state = "stand"
                    return
                end
                local s = self.object:getpos()
                local p = self.attack.player:getpos()
                local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
                if dist > self.view_range or self.attack.player:get_hp() <= 0 then
                    self.state = "stand"
                    self.v_start = false
                    self.set_velocity(self, 0)
                    self.attack = {player=nil, dist=nil}
                    return
                else
                    self.attack.dist = dist
                end
               
                local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z}
                local yaw = math.atan(vec.z/vec.x)+math.pi/2
                if self.drawtype == "side" then
                    yaw = yaw+(math.pi/2)
                end
                if p.x > s.x then
                    yaw = yaw+math.pi
                end
                self.object:setyaw(yaw)
                if self.attack.dist > 2 then
                    if not self.v_start then
                        self.v_start = true
                        self.set_velocity(self, self.run_velocity)
                    else
                        if self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
                            local v = self.object:getvelocity()
                            v.y = 5
                            self.object:setvelocity(v)
                        end
                        self.set_velocity(self, self.run_velocity)
                    end
                else
                    self.set_velocity(self, 0)
                    self.v_start = false
                    if self.timer > 1 then
                        self.timer = 0
                        local d1 = 10
                        local d2 = 10
                        local d3 = 10
                        if self.damage > 0 then
                            d3 = 1/self.damage
                        end
                        if self.damage > 1 then
                            d2 = 1/(self.damage-1)
                        end
                        if self.damage > 2 then
                            d1 = 1/(self.damage-2)
                        end
                        if self.sounds and self.sounds.attack then
                            minetest.sound_play(self.sounds.attack, {object = self.object})
                        end
                        self.attack.player:punch(self.object, 1.0,  {
                            full_punch_interval=1.0,
                            groupcaps={
                                fleshy={times={[1]=d1, [2]=d2, [3]=d3}},
                            }
                        }, vec)
                    end
                end
            elseif self.state == "attack" and self.attack_type == "shoot" then
                if not self.attack.player or not self.attack.player:is_player() then
                    self.state = "stand"
                    return
                end
                local s = self.object:getpos()
                local p = self.attack.player:getpos()
                local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
                if dist > self.view_range or self.attack.player:get_hp() <= 0 then
                    self.state = "stand"
                    self.v_start = false
                    self.set_velocity(self, 0)
                    self.attack = {player=nil, dist=nil}
                    return
                else
                    self.attack.dist = dist
                end
               
                local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z}
                local yaw = math.atan(vec.z/vec.x)+math.pi/2
                if self.drawtype == "side" then
                    yaw = yaw+(math.pi/2)
                end
                if p.x > s.x then
                    yaw = yaw+math.pi
                end
                self.object:setyaw(yaw)
                self.set_velocity(self, 0)
               
                if self.timer > self.shoot_interval and math.random(1, 100) <= 60 then
                    self.timer = 0
                   
                    if self.sounds and self.sounds.attack then
                        minetest.sound_play(self.sounds.attack, {object = self.object})
                    end
                   
                    local obj = minetest.env:add_entity(self.object:getpos(), self.arrow)
                    local amount = (vec.x^2+vec.y^2+vec.z^2)^0.5
                    local v = obj:get_luaentity().velocity
                    vec.y = vec.y+1
                    vec.x = vec.x*v/amount
                    vec.y = vec.y*v/amount
                    vec.z = vec.z*v/amount
                    obj:setvelocity(vec)
                end
            end
        end,
       
        on_activate = function(self, staticdata)
            self.object:set_armor_groups({fleshy=self.armor})
            self.object:setacceleration({x=0, y=-10, z=0})
            self.state = "stand"
            self.object:setvelocity({x=0, y=self.object:getvelocity().y, z=0})
            self.object:setyaw(math.random(1, 360)/180*math.pi)
            if self.type == "monster" and minetest.setting_getbool("only_peaceful_mobs") then
                self.object:remove()
            end
        end,
       
        on_punch = function(self, hitter)
            if self.object:get_hp() <= 0 then
                if hitter and hitter:is_player() and hitter:get_inventory() then
                    for _,drop in ipairs(self.drops) do
                        if math.random(1, drop.chance) == 1 then
                            minetest.env:add_item(self.object:getpos(), ItemStack(drop.name.." "..math.random(drop.min, drop.max)))
                        end
                    end
                else
                    for _,drop in ipairs(self.drops) do
                        if math.random(1, drop.chance) == 1 then
                            for i=1,math.random(drop.min, drop.max) do
                                local obj = minetest.env:add_item(self.object:getpos(), drop.name)
                                if obj then
                                    obj:get_luaentity().collect = true
                                    local x = math.random(1, 5)
                                    if math.random(1,2) == 1 then
                                        x = -x
                                    end
                                    local z = math.random(1, 5)
                                    if math.random(1,2) == 1 then
                                        z = -z
                                    end
                                    obj:setvelocity({x=1/x, y=obj:getvelocity().y, z=1/z})
                                end
                            end
                        end
                    end
                end
            end
        end,
       
    })
end

Nice :D
Can you create a diff against the current register_mobs function? It would make it easier to check the 3D parts.

Nevermind. I did it myself:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
diff --git a/2D.lua b/3D.lua
index 99f0ffb..535c0e8 100644
--- a/2D.lua
+++ b/3D.lua
@@ -1,10 +1,11 @@
-function mobs:register_mob(name, def)
+function mobs:register_mob_3d(name, def)
     minetest.register_entity(name, {
         hp_max = def.hp_max,
         physical = true,
         collisionbox = def.collisionbox,
         visual = def.visual,
         visual_size = def.visual_size,
+        mesh=def.mesh,
         textures = def.textures,
         makes_footstep_sound = def.makes_footstep_sound,
         view_range = def.view_range,
@@ -302,7 +303,7 @@ function mobs:register_mob(name, def)
                 if hitter and hitter:is_player() and hitter:get_inventory() then
                     for _,drop in ipairs(self.drops) do
                         if math.random(1, drop.chance) == 1 then
-                            hitter:get_inventory():add_item("main", ItemStack(drop.name.." "..math.random(drop.min, drop.max)))
+                            minetest.env:add_item(self.object:getpos(), ItemStack(drop.name.." "..math.random(drop.min, drop.max)))
                         end
                     end
                 else

Hmmm.... I thought you added some animation etc.
This has to be done.
Something like animation = {walk_start=int, walk_end=int, ...} passed to the function.
Last edited by PilzAdam on Mon Feb 04, 2013 17:35, edited 1 time in total.
 

User avatar
LorenzoVulcan
Member
 
Posts: 437
Joined: Mon Mar 12, 2012 06:46

by LorenzoVulcan » Mon Feb 04, 2013 17:34

PilzAdam wrote:Nice :D
Can you create a diff against the current register_mobs function? It would make it easier to check the 3D parts.


It's already a different function,i made a fork with some new 3d and 2d mobs some weeks ago.
Developer of the BlockForge 2# Project!
Official thread: http://minetest.net/forum/viewtopic.php?pid=54290#p54290
 

User avatar
jojoa1997
Member
 
Posts: 2890
Joined: Thu Dec 13, 2012 05:11

by jojoa1997 » Mon Feb 04, 2013 17:34

Could you make a sperate mod for 3d ones
Coding;
1X coding
3X debugging
12X tweaking to be just right
 

User avatar
PandaGaz
Member
 
Posts: 15
Joined: Wed Dec 19, 2012 01:45

by PandaGaz » Mon Feb 04, 2013 18:35

I NEED A PET DOG!
I like Pandas. I like Gaz from MW1. Panda+Gaz=PandaGaz... P.S. on RedCrab's 4.4 i am KoalaBear
 

sapier
Member
 
Posts: 763
Joined: Tue Aug 16, 2011 18:17

by sapier » Mon Feb 04, 2013 19:23

@PandaGaz have a look at mobf there already is a pet dog
DON'T mention coding style!
(c) sapier all rights reserved
 

shortstop824
New member
 
Posts: 3
Joined: Sun Jan 27, 2013 13:57

by shortstop824 » Thu Feb 07, 2013 12:42

They all have unsatisfied dependencies. What do i do?
 

User avatar
Topywo
Member
 
Posts: 1718
Joined: Fri May 18, 2012 20:27

by Topywo » Thu Feb 07, 2013 19:23

shortstop824 wrote:They all have unsatisfied dependencies. What do i do?


I assume you mean the mods in animal_modpack? It's a modpack. Try extracting the whole animal_modpack (master) in the mods/minetest folder, instead of the seperate mods in the folder below it.
 

shortstop824
New member
 
Posts: 3
Joined: Sun Jan 27, 2013 13:57

by shortstop824 » Thu Feb 07, 2013 21:34

Topywo wrote:
shortstop824 wrote:They all have unsatisfied dependencies. What do i do?


I assume you mean the mods in animal_modpack? It's a modpack. Try extracting the whole animal_modpack (master) in the mods/minetest folder, instead of the seperate mods in the folder below it.


Thanks it worked
 

User avatar
fishyWET
Member
 
Posts: 145
Joined: Tue Jan 01, 2013 07:43
GitHub: fishyWET

by fishyWET » Sun Feb 10, 2013 13:01

I am currently creating a survival map, all is left is some monsters but how do i get those monsters or do i have to wait for them to spawn with something
LOTR Subgame
Some days you flip the table, (ノಥ益ಥ)ノ ︵┻━┻,
Other days, the table flip you, ┳━┳︵(ₒ⁻ₒ).
 

User avatar
PilzAdam
Member
 
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam

by PilzAdam » Sun Feb 10, 2013 13:07

fishyWET wrote:I am currently creating a survival map, all is left is some monsters but how do i get those monsters or do i have to wait for them to spawn with something

If you lookt at the init.lua you will see a lot of register_mob() calls like this:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
mobs:register_mob("mobs:dirt_monster", {

The name in the "" is the name of the mob. You can spawn it ingame with
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
/spawnentity name

E.g.
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
/spawnentity mobs:dirt_monster
 

User avatar
fishyWET
Member
 
Posts: 145
Joined: Tue Jan 01, 2013 07:43
GitHub: fishyWET

by fishyWET » Sun Feb 10, 2013 13:08

Ok thanks that help a lot
LOTR Subgame
Some days you flip the table, (ノಥ益ಥ)ノ ︵┻━┻,
Other days, the table flip you, ┳━┳︵(ₒ⁻ₒ).
 

4aiman
Member
 
Posts: 1208
Joined: Mon Jul 30, 2012 05:47

by 4aiman » Sun Feb 10, 2013 14:39

Is there a way I can make some mob slower/not so oppressive?
They're too tough to beat if you didn't spend several hours adapting...
 

Crazycat399
New member
 
Posts: 1
Joined: Wed Feb 13, 2013 01:58

by Crazycat399 » Wed Feb 13, 2013 02:00

It wont work on mine.... :(
 

User avatar
Topywo
Member
 
Posts: 1718
Joined: Fri May 18, 2012 20:27

by Topywo » Wed Feb 13, 2013 10:02

Crazycat399 wrote:It wont work on mine.... :(


You need one of the latest versions of minetest and of this mod. One of the latest versions means newer than the stable version. But don't worry, most later versions are stable or even more stable.

If it doesn't help, delete the file debug.txt. Restart minetest completely to generate the same error. Exit and open your 'new' debug.txt. Copy the bottom part of that file (the ERROR-lines) an paste them here, so anyone can see what's wrong.

Edit: typo
Last edited by Topywo on Wed Feb 13, 2013 10:03, edited 1 time in total.
 

User avatar
Calinou
Member
 
Posts: 3124
Joined: Mon Aug 01, 2011 14:26
GitHub: Calinou
IRC: Calinou
In-game: Calinou

by Calinou » Wed Feb 13, 2013 12:18

4aiman wrote:Is there a way I can make some mob slower/not so oppressive?
They're too tough to beat if you didn't spend several hours adapting...


Tweak the "run_velocity" of the mobs (lower is slower of course).
Also, stop playing with a touchpad. :D
 

Matsetes
Member
 
Posts: 70
Joined: Tue Sep 11, 2012 23:36

by Matsetes » Sat Feb 16, 2013 09:10

I get a problem and I think is caused by your mod:
sometimes (now is all the times), when I find some mobs underground, the games blocks (you can move and dig items but they will not be in the inventory and all the changes are not saved. If you put items, they are not deleted from the inventory, the mobs cannot move and dye, even if you kill them the particles rest in the air and the mob too..)
 

User avatar
PilzAdam
Member
 
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam

by PilzAdam » Sat Feb 16, 2013 11:42

Matsetes wrote:I get a problem and I think is caused by your mod:
sometimes (now is all the times), when I find some mobs underground, the games blocks (you can move and dig items but they will not be in the inventory and all the changes are not saved. If you put items, they are not deleted from the inventory, the mobs cannot move and dye, even if you kill them the particles rest in the air and the mob too..)

Seems like the local server hang-up.
 

4aiman
Member
 
Posts: 1208
Joined: Mon Jul 30, 2012 05:47

by 4aiman » Sat Feb 16, 2013 12:56

PilzAdam wrote:
Matsetes wrote:I get a problem and I think is caused by your mod:
sometimes (now is all the times), when I find some mobs underground, the games blocks (you can move and dig items but they will not be in the inventory and all the changes are not saved. If you put items, they are not deleted from the inventory, the mobs cannot move and dye, even if you kill them the particles rest in the air and the mob too..)

Seems like the local server hang-up.


This is not an unusual behavior. I've seen this in a singleplayer as well as in multiplayer for so many times...
But the truth is that server (either local or remote) is able to "fix" that "issues" if one wait enough to let it do it's work.
Sometimes there are not enough resources and server would newer stop glitching until restart.
That happens with any version of mobs I've tried (this one, mobf, butter creeper, cactus).

The problem do not lie within a server or a client, but within their "communication" process.
 

User avatar
PilzAdam
Member
 
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam

by PilzAdam » Sat Feb 16, 2013 14:10

I have done some little tweaks:
  • The spawning per block is now limited, so not too many mobs can spawn
  • Mobs, that die without be hitted by a player dont drop their drops anymore (also increases performance)
The mod should be more usable now.
 

4aiman
Member
 
Posts: 1208
Joined: Mon Jul 30, 2012 05:47

by 4aiman » Sat Feb 16, 2013 14:40

Thanks, PilzAdam!
How about some unfair measures?
For example, if player killed a mob, then create only CAO entities with the "loot"? So it would be entirely client's problem and the server would know nothing about that CAO?
Or is your mod already uses this scheme?

Also, could you make them less aggressive? Almost any encounter when I'm not fleeing results in me being dead...
Maybe some settings if not the permanent change - there are those who like mobs as they are for now.
 

User avatar
PilzAdam
Member
 
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam

by PilzAdam » Sat Feb 16, 2013 14:48

More tweaks:
  • Further improvement of performance of spawning code
  • If enable_damage is false the mobs dont attack you
 

User avatar
PilzAdam
Member
 
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam

by PilzAdam » Sat Feb 16, 2013 14:50

4aiman wrote:Thanks, PilzAdam!
How about some unfair measures?
For example, if player killed a mob, then create only CAO entities with the "loot"? So it would be entirely client's problem and the server would know nothing about that CAO?
Or is your mod already uses this scheme?

Not possible with the current API.
4aiman wrote:Also, could you make them less aggressive? Almost any encounter when I'm not fleeing results in me being dead...
Maybe some settings if not the permanent change - there are those who like mobs as they are for now.

Yea, need to think about a system of different levels of difficutly.
 

4aiman
Member
 
Posts: 1208
Joined: Mon Jul 30, 2012 05:47

by 4aiman » Sat Feb 16, 2013 14:51

Great!
PilzAdam wrote:If enable_damage is false the mobs dont attack you

Is there an easy way to make particular type of a monster slower and/or weaker?
 

User avatar
PilzAdam
Member
 
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam

by PilzAdam » Sat Feb 16, 2013 14:52

4aiman wrote:Great!
PilzAdam wrote:If enable_damage is false the mobs dont attack you

Is there an easy way to make particular type of a monster slower and/or weaker?

Sure, look at the registration tables in init.lua. They contain "walk_velocity" and "run_velocity". The latter one is used when the mob attacks players.
 

4aiman
Member
 
Posts: 1208
Joined: Mon Jul 30, 2012 05:47

by 4aiman » Sat Feb 16, 2013 14:58

Thanks once more!
Last edited by 4aiman on Sat Feb 16, 2013 14:58, edited 1 time in total.
 

PreviousNext

Return to Mod Releases

Who is online

Users browsing this forum: No registered users and 30 guests

cron