]> git.lizzy.rs Git - Crafter.git/blob - mods/mob/pig/interaction_code.lua
Add in group_attack setting for mobs
[Crafter.git] / mods / mob / pig / interaction_code.lua
1 --this is the file which houses the functions that control how mobs interact with the world
2
3
4 --the sword wear mechanic
5 pig.add_sword_wear = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
6         if puncher:is_player() then
7                 local itemstack = puncher:get_wielded_item()
8                 local wear = itemstack:get_definition().mob_hit_wear
9                 if wear then
10                         itemstack:add_wear(wear)
11                         if itemstack:get_name() == "" then
12                                 minetest.sound_play("tool_break",{to_player = puncher:get_player_name(),gain=0.4})
13                         end
14                         puncher:set_wielded_item(itemstack)
15                 end
16         end
17 end
18
19 --critical effect particles
20 pig.do_critical_particles = function(pos)
21         minetest.add_particlespawner({
22                 amount = 40,
23                 time = 0.001,
24                 minpos = pos,
25                 maxpos = pos,
26                 minvel = vector.new(-2,-2,-2),
27                 maxvel = vector.new(2,8,2),
28                 minacc = {x=0, y=4, z=0},
29                 maxacc = {x=0, y=12, z=0},
30                 minexptime = 1.1,
31                 maxexptime = 1.5,
32                 minsize = 1,
33                 maxsize = 2,
34                 collisiondetection = false,
35                 vertical = false,
36                 texture = "critical.png",
37         })
38 end
39
40 --this controls what happens when the mob gets punched
41 pig.on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
42         local hp = self.hp
43         local vel = self.object:get_velocity()
44         local hurt = tool_capabilities.damage_groups.damage
45         
46         if not hurt then
47                 hurt = 1
48         end
49         
50         local critical = false
51         
52         --criticals
53         local pos = self.object:get_pos()
54         if puncher:is_player() then
55                 local puncher_vel = puncher:get_player_velocity().y
56                 if puncher_vel < 0 then
57                         hurt = hurt * 1.5
58                         critical = true
59                 end
60         end
61         
62         local hp = hp-hurt
63         
64         if (self.punched_timer <= 0 and hp > 1)  then
65                 self.hostile = true
66                 self.hostile_timer = 20
67                 self.punched_timer = 0.8
68                 
69                 --critical effect
70                 if critical == true then
71                         self.do_critical_particles(pos)
72                         minetest.sound_play("critical", {object=self.object, gain = 0.1, max_hear_distance = 10,pitch = math.random(80,100)/100})
73                 end
74                 minetest.sound_play("pig", {object=self.object, gain = 1.0, max_hear_distance = 10,pitch = math.random(80,100)/100})
75                 
76                 self.hp = hp
77                 
78                 self.direction = vector.multiply(dir,-1)
79                 dir = vector.multiply(dir,10)
80                 if vel.y <= 0 then
81                         dir.y = 4
82                 else
83                         dir.y = 0
84                 end
85                 
86                 
87                 self.object:add_velocity(dir)
88                 self.add_sword_wear(self, puncher, time_from_last_punch, tool_capabilities, dir)
89         elseif self.punched_timer <= 0 and self.death_animation_timer == 0 then
90                 self.death_animation_timer = 1
91                 self.dead = true
92                 
93                 --critical effect
94                 if critical == true then
95                         self.do_critical_particles(pos)
96                         minetest.sound_play("critical", {object=self.object, gain = 0.1, max_hear_distance = 10,pitch = math.random(80,100)/100})
97                 end
98                 minetest.sound_play("pig_die", {object=self.object, gain = 1.0, max_hear_distance = 10,pitch = math.random(80,100)/100})
99                 
100                 self.object:set_texture_mod("^[colorize:red:130")
101                 if self.child then
102                         self.child:set_texture_mod("^[colorize:red:130")
103                 end
104                 self.add_sword_wear(self, puncher, time_from_last_punch, tool_capabilities, dir)
105         end
106 end
107
108 --this is what happens when a mob diese
109 pig.on_death = function(self, killer)
110         local pos = self.object:getpos()
111         --pos.y = pos.y + 0.4
112         minetest.sound_play("mob_die", {pos = pos, gain = 1.0})
113         minetest.add_particlespawner({
114                 amount = 40,
115                 time = 0.001,
116                 minpos = pos,
117                 maxpos = pos,
118                 minvel = vector.new(-5,-5,-5),
119                 maxvel = vector.new(5,5,5),
120                 minacc = {x=0, y=0, z=0},
121                 maxacc = {x=0, y=0, z=0},
122                 minexptime = 1.1,
123                 maxexptime = 1.5,
124                 minsize = 1,
125                 maxsize = 2,
126                 collisiondetection = false,
127                 vertical = false,
128                 texture = "smoke.png",
129         })
130         minetest.throw_item(pos,"mob:raw_porkchop")
131         self.child:get_luaentity().parent = nil
132         self.object:remove()
133 end
134
135 --this makes the mob rotate and then die
136 pig.manage_death_animation = function(self,dtime)
137         if self.death_animation_timer >= 0 and self.dead == true then
138                 self.death_animation_timer = self.death_animation_timer - dtime
139                 
140                 local self_rotation = self.object:get_rotation()
141                 
142                 if self_rotation.z < math.pi/2 then
143                         self_rotation.z = self_rotation.z + (dtime*2)
144                         self.object:set_rotation(self_rotation)
145                 end
146                 
147                 --print(self.death_animation_timer)
148                 local currentvel = self.object:getvelocity()
149                 local goal = vector.new(0,0,0)
150                 local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
151                 acceleration = vector.multiply(acceleration, 0.05)
152                 self.object:add_velocity(acceleration)
153                 self.object:set_animation({x=0,y=0}, 15, 0, true)
154         
155                 self.return_head_to_origin(self,dtime)
156                 
157         end
158 end
159
160 --the pig will look for and at players
161 pig.look_around = function(self,dtime)
162         local pos = self.object:get_pos()
163         
164         --STARE O_O
165         --and follow!
166         self.following = false
167         local player_found = false
168         for _,object in ipairs(minetest.get_objects_inside_radius(pos, 6)) do
169                 if object:is_player() and player_found == false and object:get_hp() > 0 then
170                         --look at player's camera
171                         local pos2 = object:get_pos()
172                         pos2.y = pos2.y + 1.625
173                         
174                         player_found = true
175                         
176                         self.move_head(self,pos2,dtime)
177                         
178                         if self.hostile == true then
179                                 self.direction = vector.direction(pos,pos2)
180                                 local distance = vector.distance(pos,pos2)-2
181                                 if distance < 0 then
182                                         distance = 0
183                                 end
184                                 
185                                 --punch the player
186                                 if distance < 1 and self.punch_timer <= 0 and object:get_hp() > 0 then
187                                         local line_of_sight = minetest.line_of_sight(pos, pos2)
188                                         if line_of_sight == true then
189                                                 self.punch_timer = 1
190                                                 object:punch(self.object, 2, 
191                                                         {
192                                                         full_punch_interval=1.5,
193                                                         damage_groups = {fleshy=2},
194                                                 },vector.direction(pos,pos2))
195                                         end
196                                 end
197                                 self.speed = distance * 4
198                                 if self.speed > 6 then
199                                         self.speed = 6
200                                 end
201                                 self.following = true
202                         end
203                         --only look at one player
204                         break
205                 end
206         end
207         --stare straight if not found
208         if player_found == false then
209                 self.move_head(self,nil,dtime)
210                 self.manage_hostile_timer(self,dtime)
211         end
212 end