123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- local entity_definition = {
- initial_properties = {
- physical = true,
- collide_with_objects = false,
- weight = 5,
- collisionbox = {-0.2, -0.3, -0.2, 0.2, 0.1, 0.2},
- selectionbox = {-0.4, -0.3, -0.4, 0.4, 0.3, 0.4},
- visual = "sprite",
- textures = {"gunpowder_barrels_barrel.png"},
- },
- falling_timer = -1,
- life_timer = 0,
- fuse = nil,
- }
- entity_definition.get_staticdata = function(self)
- return ""
- end
- entity_definition.explode = gunpowder_barrels.explode
- entity_definition.on_activate = function(self, staticdata)
- if staticdata == "" --place
- then
- self.old_velocity = {x = 0, y = 0, z = 0}
- else --throw
- local vel = minetest.deserialize(staticdata)
- --make sure staticdata is a serialized vector
- assert(vel.x and vel.y and vel.z)
- --apply velocity
- self.object:setvelocity(vel)
- self.old_velocity = vel
- --light fuse
- self:start_fuse(math.random() * 100 + 100)
- end
- --falling physics
- self.object:setacceleration({x = 0, y = -9, z = 0})
- self.object:set_armor_groups({punch_operable = 1})
- end
- entity_definition.start_fuse = function(self, time)
- self.fuse_handle = minetest.sound_play(
- "gunpowder_barrels_fuse",
- {
- object = self.object,
- gain = 1,
- loop = true,
- pitch = 1.5,
- })
- self.fuse = time
- end
- entity_definition.on_step = function(self)
- if self.life_timer == 10
- then
- self.object:set_properties({collide_with_objects = true})
- end
- self.life_timer = self.life_timer + 1
- local vel = self.object:getvelocity()
- local pos = self.object:get_pos()
- if self.fuse
- then
- if self.fuse > 0
- then
- self.fuse = self.fuse - 1
- local particlepos = {x = pos.x, y = pos.y + 0.5, z = pos.z}
- local parent, bone, offset = self.object:get_attach()
- if parent
- then
- particlepos.x = particlepos.x + offset.x / 10
- particlepos.y = particlepos.y + offset.y / 10
- particlepos.z = particlepos.z + offset.z / 10
- end
- minetest.add_particle(
- {
- pos = particlepos,
- velocity = {x = 0, y = 1, z = 0},
- expirationtime = math.random() * 0.3,
- texture = "gunpowder_barrels_spark.png",
- glow = 14,
- })
- else
- self:explode()
- end
- end
- --float on water
- do
- pos.y = pos.y + 0.4
- local node_name = minetest.get_node(pos).name
- if minetest.get_item_group(node_name, "water") > 0
- then
- self.object:setacceleration({x = 0, y = 7, z = 0})
- vel = {x = vel.x * 0.7, y = vel.y * 0.9, z = vel.z * 0.7}
- self.object:setvelocity(vel)
- self.falling_timer = 0
- self.fuse = nil
- return
- else
- local downpos = {x = pos.x, y = pos.y - 1, z = pos.z}
- node_name = minetest.get_node(downpos).name
- if minetest.get_item_group(node_name, "water") > 0
- then
- --self.object:setvelocity({x = vel.x * 0.8, y = -0.01, z = vel.x * 0.8})
- self.object:setacceleration({x = 0, y = -0.2, z = 0})
- return
- end
- end
- end
- --handle falling
- if vel.y < 0
- then
- --if falling
- self.falling_timer = self.falling_timer + 1
- if self.falling_timer < 10 and self.life_timer > 10
- then
- local acc = {x = vel.x * -vel.y, y = -9, z = vel.z * -vel.y}
- self.object:setacceleration(acc)
- end
- elseif self.falling_timer > 0
- then
- --bounce
- self.falling_timer = 0
- local bounce_height = vector.length(vel) * 0.7
- --chance to explode on bounce
- if self.fuse
- then
- self.fuse = self.fuse - bounce_height * math.random()
- elseif bounce_height > 2 and math.random() > 0.9
- then
- self:start_fuse(20 * math.random())
- end
- vel = {
- x = vel.x * 0.99,
- y = vector.length(vel) * 0.5,
- z = vel.z * 0.99
- }
- self.object:setvelocity(vel)
- minetest.sound_play(
- "gunpowder_barrels_bump",
- {
- object = self.object,
- gain = bounce_height * 0.025,
- pitch = 0.5,
- max_hear_distance = 32,
- })
- end
- if self.falling_timer <= 0 or self.falling_timer >= 10
- then
- self.object:setacceleration({x = 0, y = -9, z = 0})
- if vel.y == 0
- then
- --applying friction
- vel = vector.multiply(vel, 0.99)
- self.object:setvelocity(vel)
- end
- end
- end
- --kick barrel, doesn't light fuse
- --fuse has a chance to be lit when bouncing though
- entity_definition.on_rightclick = function(self, clicker)
- if clicker
- then
- local clickerpos = clicker:get_pos()
- local kick = vector.subtract(self.object:get_pos(), clickerpos)
- kick.y = 0
- kick = vector.normalize(kick)
- kick = vector.multiply(kick, 5)
- self.object:setvelocity(kick)
- end
- end
- entity_definition.on_punch = function(self)
- --light fuse for 5 to 10 seconds
- if not self.fuse
- then
- self:start_fuse(math.random() * 100 + 100)
- else
- self.fuse = self.fuse - math.random() * 10
- end
- end
- minetest.register_entity("gunpowder_barrels:barrel_entity", entity_definition)
|