2020-07-10 13:01:21 +02:00
local S = minetest.get_translator ( " mcl_potions " )
2020-06-18 13:43:50 +02:00
local lingering_image = function ( colorstring , opacity )
if not opacity then
opacity = 127
end
2020-07-05 23:36:18 +02:00
return " mcl_potions_splash_overlay.png^[colorize: " .. colorstring .. " : " .. tostring ( opacity ) .. " ^mcl_potions_lingering_bottle.png "
2020-06-18 13:43:50 +02:00
end
2020-06-27 02:32:03 +02:00
local lingering_effect_at = { }
2020-08-05 18:33:53 +02:00
local function add_lingering_effect ( pos , color , def , is_water )
2020-06-27 02:32:03 +02:00
2020-08-05 18:33:53 +02:00
lingering_effect_at [ pos ] = { color = color , timer = 30 , def = def , is_water = is_water }
2020-06-27 02:32:03 +02:00
2020-06-28 00:50:08 +02:00
end
2020-06-27 02:32:03 +02:00
2020-06-28 00:50:08 +02:00
local lingering_timer = 0
minetest.register_globalstep ( function ( dtime )
2020-06-27 02:32:03 +02:00
2020-06-28 00:50:08 +02:00
lingering_timer = lingering_timer + dtime
if lingering_timer >= 1 then
2020-06-27 02:32:03 +02:00
2020-06-28 00:50:08 +02:00
for pos , vals in pairs ( lingering_effect_at ) do
2020-06-27 02:32:03 +02:00
2020-06-28 00:50:08 +02:00
vals.timer = vals.timer - lingering_timer
local d = 4 * ( vals.timer / 30.0 )
2020-08-05 19:26:51 +02:00
local texture
if vals.is_water then
texture = " mcl_potions_droplet.png "
else
texture = " mcl_potions_sprite.png "
end
2020-06-28 00:50:08 +02:00
minetest.add_particlespawner ( {
2020-08-05 19:26:51 +02:00
amount = 10 * d ^ 2 ,
time = 1 ,
minpos = { x = pos.x - d , y = pos.y + 0.5 , z = pos.z - d } ,
maxpos = { x = pos.x + d , y = pos.y + 1 , z = pos.z + d } ,
minvel = { x =- 0.5 , y = 0 , z =- 0.5 } ,
maxvel = { x = 0.5 , y = 0.5 , z = 0.5 } ,
minacc = { x =- 0.2 , y = 0 , z =- 0.2 } ,
maxacc = { x = 0.2 , y = .05 , z = 0.2 } ,
minexptime = 1 ,
maxexptime = 2 ,
minsize = 2 ,
maxsize = 4 ,
collisiondetection = true ,
vertical = false ,
texture = texture .. " ^[colorize: " .. vals.color .. " :127 " ,
} )
-- Extinguish fire if water bottle
2020-08-05 18:33:53 +02:00
if vals.is_water then
2020-08-05 19:44:19 +02:00
if mcl_potions._extinguish_nearby_fire ( pos , d ) then
2020-08-05 19:53:14 +02:00
vals.timer = vals.timer - 3.25
2020-08-05 18:33:53 +02:00
end
end
-- Affect players and mobs
2020-06-28 00:50:08 +02:00
for _ , obj in pairs ( minetest.get_objects_inside_radius ( pos , d ) ) do
2020-06-27 03:27:17 +02:00
2020-06-28 00:50:08 +02:00
local entity = obj : get_luaentity ( )
if obj : is_player ( ) or entity._cmi_is_mob then
2020-06-27 02:32:03 +02:00
2020-06-28 00:50:08 +02:00
vals.def . potion_fun ( obj )
2020-08-05 19:53:14 +02:00
-- TODO: Apply timer penalty only if the potion effect was acutally applied
vals.timer = vals.timer - 3.25
2020-06-27 02:32:03 +02:00
end
end
2020-06-28 00:50:08 +02:00
if vals.timer <= 0 then lingering_effect_at [ pos ] = nil end
end
lingering_timer = 0
end
end )
2020-06-27 02:32:03 +02:00
2020-07-12 13:59:29 +02:00
function mcl_potions . register_lingering ( name , descr , color , def )
2020-06-18 13:43:50 +02:00
local id = " mcl_potions: " .. name .. " _lingering "
2020-08-01 03:20:52 +02:00
local longdesc = def.longdesc
if not def.no_effect then
longdesc = S ( " A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect, possibly repeatedly. " )
if def.longdesc then
longdesc = longdesc .. " \n " .. def.longdesc
end
end
2020-06-18 13:43:50 +02:00
minetest.register_craftitem ( id , {
description = descr ,
2020-07-06 00:04:16 +02:00
_tt_help = def.tt ,
2020-08-01 03:20:52 +02:00
_doc_items_longdesc = longdesc ,
_doc_items_usagehelp = S ( " Use the “Punch” key to throw it. " ) ,
2020-06-18 13:43:50 +02:00
inventory_image = lingering_image ( color ) ,
2020-06-28 15:38:06 +02:00
groups = { brewitem = 1 , not_in_creative_inventory = 0 } ,
2020-06-18 13:43:50 +02:00
on_use = function ( item , placer , pointed_thing )
local velocity = 10
local dir = placer : get_look_dir ( ) ;
local pos = placer : getpos ( ) ;
2020-07-12 18:16:26 +02:00
local obj = minetest.add_entity ( { x = pos.x + dir.x , y = pos.y + 2 + dir.y , z = pos.z + dir.z } , id .. " _flying " )
2020-06-18 13:43:50 +02:00
obj : setvelocity ( { x = dir.x * velocity , y = dir.y * velocity , z = dir.z * velocity } )
2020-07-12 02:34:19 +02:00
obj : setacceleration ( { x = dir.x *- 3 , y =- 9.8 , z = dir.z *- 3 } )
2020-07-12 18:16:26 +02:00
obj : get_luaentity ( ) . _thrower = placer : get_player_name ( )
2020-07-10 16:08:40 +02:00
if not minetest.is_creative_enabled ( placer : get_player_name ( ) ) then
2020-06-27 01:08:41 +02:00
item : take_item ( )
end
2020-06-18 13:43:50 +02:00
return item
end ,
2020-06-27 02:32:03 +02:00
stack_max = 1 ,
2020-07-11 15:07:27 +02:00
_on_dispense = function ( stack , dispenserpos , droppos , dropnode , dropdir )
local s_pos = vector.add ( dispenserpos , vector.multiply ( dropdir , 0.51 ) )
local obj = minetest.add_entity ( { x = s_pos.x + dropdir.x , y = s_pos.y + dropdir.y , z = s_pos.z + dropdir.z } , id .. " _flying " )
local velocity = 22
obj : set_velocity ( { x = dropdir.x * velocity , y = dropdir.y * velocity , z = dropdir.z * velocity } )
obj : set_acceleration ( { x = dropdir.x *- 3 , y =- 9.8 , z = dropdir.z *- 3 } )
end
2020-06-18 13:43:50 +02:00
} )
local w = 0.7
minetest.register_entity ( id .. " _flying " , {
textures = { lingering_image ( color ) } ,
hp_max = 1 ,
visual_size = { x = w / 2 , y = w / 2 } ,
2020-08-05 20:36:44 +02:00
collisionbox = { - 0.1 , - 0.1 , - 0.1 , 0.1 , 0.1 , 0.1 } ,
pointable = false ,
2020-06-18 13:43:50 +02:00
on_step = function ( self , dtime )
2020-08-05 18:33:53 +02:00
local pos = self.object : get_pos ( )
2020-06-18 13:43:50 +02:00
local node = minetest.get_node ( pos )
local n = node.name
2020-08-06 23:30:28 +02:00
local g = minetest.get_node_group ( n , " liquid " )
2020-06-27 03:27:17 +02:00
local d = 4
2020-08-06 23:30:28 +02:00
if n ~= " air " and n ~= " mcl_portals:portal " and n ~= " mcl_portals:portal_end " and g == 0 or mcl_potions.is_obj_hit ( self , pos ) then
2020-06-21 14:39:08 +02:00
minetest.sound_play ( " mcl_potions_breaking_glass " , { pos = pos , max_hear_distance = 16 , gain = 1 } )
2020-08-05 18:33:53 +02:00
add_lingering_effect ( pos , color , def , name == " water " )
2020-08-05 19:26:51 +02:00
local texture , minacc , maxacc
if name == " water " then
texture = " mcl_potions_droplet.png "
minacc = { x =- 0.2 , y =- 0.05 , z =- 0.2 }
maxacc = { x = 0.2 , y = 0.05 , z = 0.2 }
else
texture = " mcl_potions_sprite.png "
minacc = { x =- 0.2 , y = 0 , z =- 0.2 }
maxacc = { x = 0.2 , y = .05 , z = 0.2 }
end
2020-06-27 03:27:17 +02:00
minetest.add_particlespawner ( {
2020-08-05 19:26:51 +02:00
amount = 40 ,
time = 1 ,
minpos = { x = pos.x - d , y = pos.y + 0.5 , z = pos.z - d } ,
maxpos = { x = pos.x + d , y = pos.y + 1 , z = pos.z + d } ,
minvel = { x =- 0.5 , y = 0 , z =- 0.5 } ,
maxvel = { x = 0.5 , y = 0.5 , z = 0.5 } ,
minacc = minacc ,
maxacc = maxacc ,
minexptime = 1 ,
maxexptime = 2 ,
minsize = 1 ,
maxsize = 2 ,
collisiondetection = true ,
vertical = false ,
texture = texture .. " ^[colorize: " .. color .. " :127 " ,
} )
2020-08-05 18:33:53 +02:00
if name == " water " then
2020-08-05 19:44:19 +02:00
mcl_potions._extinguish_nearby_fire ( pos , d )
2020-08-05 18:33:53 +02:00
end
2020-06-27 02:32:03 +02:00
self.object : remove ( )
2020-06-18 13:43:50 +02:00
end
end ,
} )
end
2020-07-12 13:59:29 +02:00
-- -- register_lingering("weakness", S("Lingering Weakness Potion"), "#6600AA", {
-- -- potion_fun = function(player) mcl_potions.weakness_func(player, -4, mcl_potions.DURATION*mcl_potions.INV_FACTOR*0.25) end,
-- -- -- TODO: Fix tooltip
-- -- tt = time_string(mcl_potions.DURATION*mcl_potions.INV_FACTOR*0.25)
-- -- })
-- --
-- -- register_lingering("weakness_plus", S("Lingering Weakness Potion +"), "#7700BB", {
-- -- potion_fun = function(player) mcl_potions.weakness_func(player, -4, mcl_potions.DURATION_PLUS*mcl_potions.INV_FACTOR*0.25) end,
-- -- -- TODO: Fix tooltip
-- -- tt = time_string(mcl_potions.DURATION*mcl_potions.INV_FACTOR*0.25)
-- -- })
-- --
-- -- register_lingering("strength", S("Lingering Strength Potion"), "#D444D4", {
-- -- potion_fun = function(player) mcl_potions.strength_func(player, 3, mcl_potions.DURATION*0.25) end,
-- -- -- TODO: Fix tooltip
-- -- tt = time_string(mcl_potions.DURATION*0.25)
-- -- })
-- --
-- -- register_lingering("strength_2", S("Lingering Strength Potion II"), "#D444F4", {
-- -- potion_fun = function(player) mcl_potions.strength_func(player, 6, smcl_potions.DURATION_2*0.25) end,
-- -- -- TODO: Fix tooltip
-- -- tt = time_string(mcl_potions.DURATION_2*0.25)
-- -- })
-- --
-- -- register_lingering("strength_plus", S("Lingering Strength Potion +"), "#D444E4", {
-- -- potion_fun = function(player) mcl_potions.strength_func(player, 3, mcl_potions.DURATION_PLUS*0.25) end,
-- -- -- TODO: Fix tooltip
-- -- tt = time_string(mcl_potions.DURATION_PLUS*0.25)
-- -- })