]> git.lizzy.rs Git - Crafter.git/blob - mods/mob/init.lua
b0f23a3154433d62e20049ed04b2f298390f8805
[Crafter.git] / mods / mob / init.lua
1 --this is where mobs are defined
2
3 global_mob_table = {}
4
5
6 local path = minetest.get_modpath(minetest.get_current_modname())
7
8 dofile(path.."/spawning.lua")
9 dofile(path.."/items.lua")
10
11
12 --these are helpers to create entities
13 local mob = {}
14 mob.initial_properties = {
15         hp_max = 1,
16         physical = true,
17         collide_with_objects = false,
18         collisionbox = {-0.37, -0.01, -0.37, 0.37, 0.865, 0.37},
19         visual = "mesh",
20         visual_size = {x = 3, y = 3},
21         mesh = "pig.b3d",
22         textures = {
23                 "pig.png","pig.png","pig.png","pig.png","pig.png","pig.png","pig.png","pig.png","pig.png","pig.png"
24         },
25         is_visible = true,
26         pointable = true,
27         automatic_face_movement_dir = -90.0,
28         automatic_face_movement_max_rotation_per_sec = 600,
29 }
30 mob.hp = 5
31 mob.mob = true
32 mob.hostile = false
33 mob.timer = 0
34
35
36 mob.get_staticdata = function(self)
37         return minetest.serialize({
38                 --range = self.range,
39                 hp = self.hp,           
40         })
41 end
42 mob.on_activate = function(self, staticdata, dtime_s)
43         self.object:set_armor_groups({immortal = 1})
44         --self.object:set_velocity({x = math.random(-5,5), y = 5, z = math.random(-5,5)})
45         self.object:set_acceleration({x = 0, y = -9.81, z = 0})
46         if string.sub(staticdata, 1, string.len("return")) == "return" then
47                 local data = minetest.deserialize(staticdata)
48                 if data and type(data) == "table" then
49                         --self.range = data.range
50                         self.hp = data.hp
51                 end
52         end
53         self.object:set_animation({x=0,y=40}, 20, 0, true)
54         self.object:set_hp(self.hp)
55         self.direction = vector.new(math.random()*math.random(-1,1),0,math.random()*math.random(-1,1))
56 end
57 mob.on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)            
58         local hurt = tool_capabilities.damage_groups.fleshy
59         if not hurt then
60                 hurt = 1
61         end
62         local hp = self.object:get_hp()
63         self.object:set_hp(hp-hurt)
64         if hp > 1 then
65                 minetest.sound_play("hurt", {object=self.object, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
66         end
67         self.hp = hp-hurt
68 end
69 mob.on_death = function(self, killer)
70         local pos = self.object:getpos()
71         pos.y = pos.y + 0.4
72         minetest.sound_play("mob_die", {pos = pos, gain = 1.0})
73         minetest.add_particlespawner({
74                 amount = 40,
75                 time = 0.001,
76                 minpos = pos,
77                 maxpos = pos,
78                 minvel = vector.new(-5,-5,-5),
79                 maxvel = vector.new(5,5,5),
80                 minacc = {x=0, y=0, z=0},
81                 maxacc = {x=0, y=0, z=0},
82                 minexptime = 1.1,
83                 maxexptime = 1.5,
84                 minsize = 1,
85                 maxsize = 2,
86                 collisiondetection = false,
87                 vertical = false,
88                 texture = "smoke.png",
89         })
90         local obj = minetest.add_item(pos,"mob:raw_porkchop")
91 end
92 --repel from players
93 mob.push = function(self)
94         local pos = self.object:getpos()
95         local radius = 1
96         for _,object in ipairs(minetest.get_objects_inside_radius(pos, radius)) do
97                 if object:is_player() or object:get_luaentity().mob == true then
98                         local player_pos = object:getpos()
99                         pos.y = 0
100                         player_pos.y = 0
101                         
102                         local currentvel = self.object:getvelocity()
103                         local vel = vector.subtract(pos, player_pos)
104                         vel = vector.normalize(vel)
105                         local distance = vector.distance(pos,player_pos)
106                         distance = (radius-distance)*10
107                         vel = vector.multiply(vel,distance)
108                         local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z)
109                         
110                         
111                         self.object:add_velocity(acceleration)
112                         
113                         acceleration = vector.multiply(acceleration, -0.5)
114                         object:add_player_velocity(acceleration)
115                 end
116         end
117 end
118 --This makes the mob walk at a certain speed and jump
119 mob.move = function(self,dtime)
120         self.timer = self.timer - dtime
121         if self.timer <= 0 then
122                 self.timer = math.random(1,3)
123                 self.direction = vector.new(math.random()*math.random(-1,1),0,math.random()*math.random(-1,1))
124         end
125         local pos1 = self.object:getpos()
126         local currentvel = self.object:getvelocity()
127         local goal = vector.multiply(self.direction,5)
128         local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
129         acceleration = vector.multiply(acceleration, 0.5)
130         self.object:add_velocity(acceleration)
131         --try to jump
132         if currentvel.y <= 0 then
133                 local in_front = minetest.raycast(pos1, vector.add(pos1,vector.multiply(self.direction,3)), false, false):next()
134                 local below = minetest.raycast(pos1, vector.add(pos1, vector.new(0,-0.02,0)), false, false):next()
135                 if in_front then
136                         in_front = minetest.registered_nodes[minetest.get_node(in_front.under).name].walkable
137                 end
138                 if below then
139                         below = minetest.registered_nodes[minetest.get_node(below.under).name].walkable
140                 end
141                 
142                 if in_front and below then
143                         self.object:add_velocity(vector.new(0,5,0))
144                 end
145         end
146 end
147 --makes the mob swim
148 mob.swim = function(self)
149         local pos = self.object:getpos()
150         pos.y = pos.y + 0.7
151         local node = minetest.get_node(pos).name
152         local vel = self.object:getvelocity()
153         local goal = 3
154         local acceleration = vector.new(0,goal-vel.y,0)
155         self.swimming = false
156         
157         if node == "main:water" or node =="main:waterflow" then
158                 self.swimming = true
159                 self.object:add_velocity(acceleration)
160         end
161 end
162 --sets the mob animation and speed
163 mob.set_animation = function(self)
164         local distance = vector.distance(vector.new(0,0,0), self.object:getvelocity())
165         self.object:set_animation_frame_speed(distance*20)
166 end
167 mob.on_step = function(self, dtime)
168         self.move(self,dtime)
169         self.set_animation(self)
170 end
171 minetest.register_entity("mob:pig", mob)