Add critical hit particles for bow

This commit is contained in:
Wuzzy 2020-08-19 14:45:37 +02:00
parent fa9ce11ddd
commit 4acf953334
4 changed files with 36 additions and 4 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

View File

@ -87,6 +87,7 @@ local ARROW_ENTITY={
_lastpos={}, _lastpos={},
_startpos=nil, _startpos=nil,
_damage=1, -- Damage on impact _damage=1, -- Damage on impact
_is_critical=false, -- Whether this arrow would deal critical damage
_stuck=false, -- Whether arrow is stuck _stuck=false, -- Whether arrow is stuck
_stucktimer=nil,-- Amount of time (in seconds) the arrow has been stuck so far _stucktimer=nil,-- Amount of time (in seconds) the arrow has been stuck so far
_stuckrechecktimer=nil,-- An additional timer for periodically re-checking the stuck status of an arrow _stuckrechecktimer=nil,-- An additional timer for periodically re-checking the stuck status of an arrow
@ -107,6 +108,28 @@ local spawn_item = function(self, pos)
self.object:remove() self.object:remove()
end end
local damage_particles = function(pos, is_critical)
if is_critical then
minetest.add_particlespawner({
amount = 15,
time = 0.1,
minpos = {x=pos.x-0.5, y=pos.y-0.5, z=pos.z-0.5},
maxpos = {x=pos.x+0.5, y=pos.y+0.5, z=pos.z+0.5},
minvel = {x=-0.1, y=-0.1, z=-0.1},
maxvel = {x=0.1, y=0.1, z=0.1},
minacc = {x=0, y=0, z=0},
maxacc = {x=0, y=0, z=0},
minexptime = 1,
maxexptime = 2,
minsize = 1.5,
maxsize = 1.5,
collisiondetection = false,
vertical = false,
texture = "mcl_particles_crit.png^[colorize:#bc7a57:127",
})
end
end
ARROW_ENTITY.on_step = function(self, dtime) ARROW_ENTITY.on_step = function(self, dtime)
local pos = self.object:get_pos() local pos = self.object:get_pos()
local dpos = table.copy(pos) -- digital pos local dpos = table.copy(pos) -- digital pos
@ -218,18 +241,21 @@ ARROW_ENTITY.on_step = function(self, dtime)
-- Punch target object but avoid hurting enderman. -- Punch target object but avoid hurting enderman.
if lua then if lua then
if lua.name ~= "mobs_mc:enderman" then if lua.name ~= "mobs_mc:enderman" then
damage_particles(self.object:get_pos(), self._is_critical)
obj:punch(self.object, 1.0, { obj:punch(self.object, 1.0, {
full_punch_interval=1.0, full_punch_interval=1.0,
damage_groups={fleshy=self._damage}, damage_groups={fleshy=self._damage},
}, nil) }, nil)
end end
else else
damage_particles(self.object:get_pos(), self._is_critical)
obj:punch(self.object, 1.0, { obj:punch(self.object, 1.0, {
full_punch_interval=1.0, full_punch_interval=1.0,
damage_groups={fleshy=self._damage}, damage_groups={fleshy=self._damage},
}, nil) }, nil)
end end
if is_player then if is_player then
if self._shooter and self._shooter:is_player() then if self._shooter and self._shooter:is_player() then
-- “Ding” sound for hitting another player -- “Ding” sound for hitting another player
@ -352,6 +378,7 @@ ARROW_ENTITY.get_staticdata = function(self)
lastpos = self._lastpos, lastpos = self._lastpos,
startpos = self._startpos, startpos = self._startpos,
damage = self._damage, damage = self._damage,
is_critical = self._is_critical,
stuck = self._stuck, stuck = self._stuck,
stuckin = self._stuckin, stuckin = self._stuckin,
} }
@ -393,6 +420,7 @@ ARROW_ENTITY.on_activate = function(self, staticdata, dtime_s)
self._lastpos = data.lastpos self._lastpos = data.lastpos
self._startpos = data.startpos self._startpos = data.startpos
self._damage = data.damage self._damage = data.damage
self._is_critical = data.is_critical
if data.shootername then if data.shootername then
local shooter = minetest.get_player_by_name(data.shootername) local shooter = minetest.get_player_by_name(data.shootername)
if shooter and shooter:is_player() then if shooter and shooter:is_player() then

View File

@ -33,7 +33,7 @@ local bow_load = {}
-- Another player table, this one stores the wield index of the bow being charged -- Another player table, this one stores the wield index of the bow being charged
local bow_index = {} local bow_index = {}
mcl_bows.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damage) mcl_bows.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damage, is_critical)
local obj = minetest.add_entity({x=pos.x,y=pos.y,z=pos.z}, arrow_item.."_entity") local obj = minetest.add_entity({x=pos.x,y=pos.y,z=pos.z}, arrow_item.."_entity")
if power == nil then if power == nil then
power = BOW_MAX_SPEED --19 power = BOW_MAX_SPEED --19
@ -47,6 +47,7 @@ mcl_bows.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damag
local le = obj:get_luaentity() local le = obj:get_luaentity()
le._shooter = shooter le._shooter = shooter
le._damage = damage le._damage = damage
le._is_critical = is_critical
le._startpos = pos le._startpos = pos
minetest.sound_play("mcl_bows_bow_shoot", {pos=pos}, true) minetest.sound_play("mcl_bows_bow_shoot", {pos=pos}, true)
if shooter ~= nil and shooter:is_player() then if shooter ~= nil and shooter:is_player() then
@ -72,7 +73,7 @@ local get_arrow = function(player)
return arrow_stack, arrow_stack_id return arrow_stack, arrow_stack_id
end end
local player_shoot_arrow = function(itemstack, player, power, damage) local player_shoot_arrow = function(itemstack, player, power, damage, is_critical)
local arrow_stack, arrow_stack_id = get_arrow(player) local arrow_stack, arrow_stack_id = get_arrow(player)
local arrow_itemstring = arrow_stack:get_name() local arrow_itemstring = arrow_stack:get_name()
@ -92,7 +93,7 @@ local player_shoot_arrow = function(itemstack, player, power, damage)
if not arrow_itemstring then if not arrow_itemstring then
arrow_itemstring = "mcl_bows:arrow" arrow_itemstring = "mcl_bows:arrow"
end end
mcl_bows.shoot_arrow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, dir, yaw, player, power, damage) mcl_bows.shoot_arrow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, dir, yaw, player, power, damage, is_critical)
return true return true
end end
@ -191,12 +192,14 @@ controls.register_on_release(function(player, key, time)
-- Calculate damage and speed -- Calculate damage and speed
-- Fully charged -- Fully charged
local is_critical = false
if charge >= BOW_CHARGE_TIME_FULL then if charge >= BOW_CHARGE_TIME_FULL then
speed = BOW_MAX_SPEED speed = BOW_MAX_SPEED
local r = math.random(1,5) local r = math.random(1,5)
if r == 1 then if r == 1 then
-- 20% chance for critical hit -- 20% chance for critical hit
damage = 10 damage = 10
is_critical = true
else else
damage = 9 damage = 9
end end
@ -207,7 +210,7 @@ controls.register_on_release(function(player, key, time)
damage = math.max(1, math.floor(9 * charge_ratio)) damage = math.max(1, math.floor(9 * charge_ratio))
end end
has_shot = player_shoot_arrow(wielditem, player, speed, damage) has_shot = player_shoot_arrow(wielditem, player, speed, damage, is_critical)
wielditem:set_name("mcl_bows:bow") wielditem:set_name("mcl_bows:bow")
if has_shot and not minetest.is_creative_enabled(player:get_player_name()) then if has_shot and not minetest.is_creative_enabled(player:get_player_name()) then

View File

@ -7,3 +7,4 @@ playerphysics?
doc? doc?
doc_identifier? doc_identifier?
mesecons_button? mesecons_button?
mcl_particles