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