diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_crit.png b/mods/CORE/mcl_particles/textures/mcl_particles_crit.png new file mode 100644 index 000000000..5b7fd3f6e Binary files /dev/null and b/mods/CORE/mcl_particles/textures/mcl_particles_crit.png differ diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index ad65eb122..b3e16d907 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -87,6 +87,7 @@ local ARROW_ENTITY={ _lastpos={}, _startpos=nil, _damage=1, -- Damage on impact + _is_critical=false, -- Whether this arrow would deal critical damage _stuck=false, -- Whether arrow is stuck _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 @@ -107,6 +108,28 @@ local spawn_item = function(self, pos) self.object:remove() 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) local pos = self.object:get_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. if lua then if lua.name ~= "mobs_mc:enderman" then + damage_particles(self.object:get_pos(), self._is_critical) obj:punch(self.object, 1.0, { full_punch_interval=1.0, damage_groups={fleshy=self._damage}, }, nil) end else + damage_particles(self.object:get_pos(), self._is_critical) obj:punch(self.object, 1.0, { full_punch_interval=1.0, damage_groups={fleshy=self._damage}, }, nil) end + if is_player then if self._shooter and self._shooter:is_player() then -- “Ding” sound for hitting another player @@ -352,6 +378,7 @@ ARROW_ENTITY.get_staticdata = function(self) lastpos = self._lastpos, startpos = self._startpos, damage = self._damage, + is_critical = self._is_critical, stuck = self._stuck, stuckin = self._stuckin, } @@ -393,6 +420,7 @@ ARROW_ENTITY.on_activate = function(self, staticdata, dtime_s) self._lastpos = data.lastpos self._startpos = data.startpos self._damage = data.damage + self._is_critical = data.is_critical if data.shootername then local shooter = minetest.get_player_by_name(data.shootername) if shooter and shooter:is_player() then diff --git a/mods/ITEMS/mcl_bows/bow.lua b/mods/ITEMS/mcl_bows/bow.lua index 68bee1a5f..12c99b358 100644 --- a/mods/ITEMS/mcl_bows/bow.lua +++ b/mods/ITEMS/mcl_bows/bow.lua @@ -33,7 +33,7 @@ local bow_load = {} -- Another player table, this one stores the wield index of the bow being charged 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") if power == nil then 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() le._shooter = shooter le._damage = damage + le._is_critical = is_critical le._startpos = pos minetest.sound_play("mcl_bows_bow_shoot", {pos=pos}, true) if shooter ~= nil and shooter:is_player() then @@ -72,7 +73,7 @@ local get_arrow = function(player) return arrow_stack, arrow_stack_id 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_itemstring = arrow_stack:get_name() @@ -92,7 +93,7 @@ local player_shoot_arrow = function(itemstack, player, power, damage) if not arrow_itemstring then arrow_itemstring = "mcl_bows:arrow" 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 end @@ -191,12 +192,14 @@ controls.register_on_release(function(player, key, time) -- Calculate damage and speed -- Fully charged + local is_critical = false if charge >= BOW_CHARGE_TIME_FULL then speed = BOW_MAX_SPEED local r = math.random(1,5) if r == 1 then -- 20% chance for critical hit damage = 10 + is_critical = true else damage = 9 end @@ -207,7 +210,7 @@ controls.register_on_release(function(player, key, time) damage = math.max(1, math.floor(9 * charge_ratio)) 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") if has_shot and not minetest.is_creative_enabled(player:get_player_name()) then diff --git a/mods/ITEMS/mcl_bows/depends.txt b/mods/ITEMS/mcl_bows/depends.txt index 08132ddbf..130c4acea 100644 --- a/mods/ITEMS/mcl_bows/depends.txt +++ b/mods/ITEMS/mcl_bows/depends.txt @@ -7,3 +7,4 @@ playerphysics? doc? doc_identifier? mesecons_button? +mcl_particles