1
0
Fork 0

Merge pull request 'Potions API redo' (#4130) from potions_api_redo into master

Reviewed-on: VoxeLibre/VoxeLibre#4130
This commit is contained in:
the-real-herowl 2024-05-22 19:05:19 +00:00
commit 52d5ec4248
122 changed files with 4194 additions and 1937 deletions

View File

@ -1,5 +1,7 @@
mcl_util = {}
dofile(minetest.get_modpath(minetest.get_current_modname()).."/roman_numerals.lua")
-- Updates all values in t using values from to*.
function table.update(t, ...)
for _, to in ipairs {...} do
@ -436,10 +438,11 @@ function mcl_util.generate_on_place_plant_function(condition)
if not def_under or not def_above then
return itemstack
end
if def_under.buildable_to then
if def_under.buildable_to and def_under.name ~= itemstack:get_name() then
place_pos = pointed_thing.under
elseif def_above.buildable_to then
elseif def_above.buildable_to and def_above.name ~= itemstack:get_name() then
place_pos = pointed_thing.above
pointed_thing.under = pointed_thing.above
else
return itemstack
end

View File

@ -0,0 +1,30 @@
local converter = {
{1000, "M"},
{900, "CM"},
{500, "D"},
{400, "CD"},
{100, "C"},
{90, "XC"},
{50, "L"},
{40, "XL"},
{10, "X"},
{9, "IX"},
{5, "V"},
{4, "IV"},
{1, "I"}
}
mcl_util.to_roman = function(number)
local r = ""
local a = number
local i = 1
while a > 0 do
if a >= converter[i][1] then
a = a - converter[i][1]
r = r.. converter[i][2]
else
i = i + 1
end
end
return r
end

View File

@ -127,6 +127,7 @@ local function try_object_pickup(player, inv, object, checkpos)
-- Add what we can to the inventory
local itemstack = ItemStack(le.itemstring)
tt.reload_itemstack_description(itemstack)
local leftovers = inv:add_item("main", itemstack )
check_pickup_achievements(object, player)

View File

@ -96,15 +96,23 @@ function mob_class:get_staticdata()
local tmp = {}
for _,stat in pairs(self) do
for tag, stat in pairs(self) do
local t = type(stat)
if t ~= "function"
and t ~= "nil"
and t ~= "userdata"
and _ ~= "_cmi_components" then
tmp[_] = self[_]
and tag ~= "_cmi_components" then
tmp[tag] = self[tag]
end
end
tmp._mcl_potions = self._mcl_potions
if tmp._mcl_potions then
for name_raw, data in pairs(tmp._mcl_potions) do
local def = mcl_potions.registered_effects[name_raw:match("^_EF_(.+)$")]
if def and def.on_save_effect then def.on_save_effect(self.object) end
end
end
@ -306,7 +314,10 @@ function mob_class:mob_activate(staticdata, def, dtime)
self._run_armor_init = true
end
if not self._mcl_potions then
self._mcl_potions = {}
end
mcl_potions._load_entity_effects(self)
if def.after_activate then

View File

@ -78,6 +78,7 @@ function mob_class:feed_tame(clicker, feed_count, breed, tame, notake)
self.food = 0
self.horny = true
self.persistent = true
self._luck = mcl_luck.get_luck(clicker:get_player_name())
end
end
@ -273,7 +274,7 @@ function mob_class:check_breeding()
return
end
mcl_experience.throw_xp(pos, math.random(1, 7))
mcl_experience.throw_xp(pos, math.random(1, 7) + (parent1._luck or 0) + (parent2._luck or 0))
-- custom breed function
if parent1.on_breed then

View File

@ -21,8 +21,6 @@ local function atan(x)
end
end
mcl_mobs.effect_functions = {}
-- check if daytime and also if mob is docile during daylight hours
function mob_class:day_docile()
@ -534,6 +532,8 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
if self.protected and minetest.is_protected(mob_pos, hitter:get_player_name()) then
return
end
mcl_potions.update_haste_and_fatigue(hitter)
end
local time_now = minetest.get_us_time()
@ -605,6 +605,13 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
* tmp * ((armor[group] or 0) / 100.0)
end
-- strength and weakness effects
local strength = mcl_potions.get_effect(hitter, "strength")
local weakness = mcl_potions.get_effect(hitter, "weakness")
local str_fac = strength and strength.factor or 1
local weak_fac = weakness and weakness.factor or 1
damage = damage * str_fac * weak_fac
if weapon then
local fire_aspect_level = mcl_enchanting.get_enchantment(weapon, "fire_aspect")
if fire_aspect_level > 0 then
@ -1144,9 +1151,8 @@ function mob_class:do_states_attack (dtime)
damage_groups = {fleshy = self.damage}
}, nil)
if self.dealt_effect then
mcl_mobs.effect_functions[self.dealt_effect.name](
self.attack, self.dealt_effect.factor, self.dealt_effect.dur
)
mcl_potions.give_effect_by_level(self.dealt_effect.name, self.attack,
self.dealt_effect.level, self.dealt_effect.dur)
end
end
else

View File

@ -325,6 +325,7 @@ function mcl_mobs.register_mob(name, def)
attack_exception = def.attack_exception or function(p) return false end,
_spawner = def._spawner,
_mcl_potions = {},
}
if minetest.get_modpath("doc_identifier") ~= nil then

View File

@ -1,5 +1,5 @@
name = mcl_mobs
author = PilzAdam
description = Adds a mob API for mods to add animals or monsters, etc.
depends = mcl_particles
depends = mcl_particles, mcl_luck
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience, mcl_sculk

View File

@ -684,7 +684,7 @@ function mob_class:do_env_damage()
self.object:set_velocity({x = 0, y = 0, z = 0})
-- wither rose effect
elseif self.standing_in == "mcl_flowers:wither_rose" then
mcl_potions.withering_func(self.object, 1, 2)
mcl_potions.give_effect_by_level("withering", self.object, 2, 2)
end
local nodef = minetest.registered_nodes[self.standing_in]

3
mods/ENTITIES/mcl_mobs/spawning.lua Executable file → Normal file
View File

@ -565,6 +565,9 @@ function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_
return
end
assert(min_height)
assert(max_height)
-- chance/spawn number override in minetest.conf for registered mob
local numbers = minetest.settings:get(name)

View File

@ -99,9 +99,7 @@ mcl_mobs.register_mob("mobs_mc:guardian", {
view_range = 16,
})
-- Spawning disabled due to size issues
-- TODO: Re-enable spawning
--mcl_mobs:spawn_specific("mobs_mc:guardian", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level - 10)
mcl_mobs:spawn_specific("mobs_mc:guardian", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level - 10, mobs_mc.water_level)
mcl_mobs:non_spawn_specific("mobs_mc:guardian","overworld",0,minetest.LIGHT_MAX+1)
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:guardian", S("Guardian"), "#5a8272", "#f17d31", 0)

View File

@ -105,11 +105,14 @@ mcl_mobs.register_mob("mobs_mc:guardian_elder", {
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
jump = false,
view_range = 16,
dealt_effect = {
name = "fatigue",
level = 3,
dur = 30,
},
})
-- Spawning disabled due to size issues <- what do you mean? -j4i
-- TODO: Re-enable spawning
-- mcl_mobs:spawn_specific("mobs_mc:guardian_elder", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level-18)
mcl_mobs:spawn_specific("mobs_mc:guardian_elder", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level-18, mobs_mc.water_level)
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "#ceccba", "#747693", 0)

View File

@ -113,7 +113,8 @@ local skeleton = {
self.object:set_yaw(minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos())))
end
local dmg = math.random(2, 4)
mcl_bows.shoot_arrow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg)
local arrow = self.arrow:match("^(.+)_entity$")
mcl_bows.shoot_arrow(arrow, pos, dir, self.object:get_yaw(), self.object, nil, dmg)
end
end,
shoot_interval = 2,
@ -140,10 +141,10 @@ stray.textures = {
"mcl_bows_bow_0.png",
},
}
stray.arrow = "mcl_potions:frost_arrow_entity"
-- TODO: different sound (w/ echo)
-- TODO: stray's arrow inflicts slowness status
table.insert(stray.drops, {
name = "mcl_potions:slowness_arrow",
name = "mcl_potions:frost_arrow",
chance = 2,
min = 1,
max = 1,
@ -152,13 +153,20 @@ table.insert(stray.drops, {
local chance = 0.5
for i = 1, lvl do
if chance > 1 then
return 1
return 1 -- TODO verify this logic, I think this is not how chance works
end
chance = chance + (1 - chance) / 2
end
return chance
end,
})
table.insert(stray.drops, {
name = "mcl_mobitems:shiny_ice_crystal",
chance = 3,
min = 1,
max = 2,
looting = "rare",
})
mcl_mobs.register_mob("mobs_mc:stray", stray)

View File

@ -98,7 +98,7 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", {
fire_resistant = true,
dealt_effect = {
name = "withering",
factor = 1,
level = 1,
dur = 10,
},
})

View File

@ -138,7 +138,7 @@ cave_spider.sounds = table.copy(spider.sounds)
cave_spider.sounds.base_pitch = 1.25
cave_spider.dealt_effect = {
name = "poison",
factor = 2.5,
level = 2,
dur = 7,
}
mcl_mobs.register_mob("mobs_mc:cave_spider", cave_spider)

View File

@ -608,6 +608,8 @@ local professions = {
{
{ { "mcl_nether:nether_wart_item", 22, 22 }, E1 },
{ { "mcl_core:emerald", 3, 3 }, { "mcl_experience:bottle", 1, 1 } },
{ { "mcl_core:emerald", 15, 15 }, { "mcl_mobitems:aery_charge", 1, 1 } }, -- TODO reconsider
{ { "mcl_core:emerald", 15, 15 }, { "mcl_mobitems:earthen_ash", 1, 1 } }, -- TODO reconsider
},
},
},

View File

@ -349,7 +349,7 @@ mcl_mobs.register_mob("mobs_mc:wither", {
mcl_util.deal_damage(objs[n], 8, {type = "magic"})
hit_some = true
end
mcl_mobs.effect_functions["withering"](objs[n], 0.5, 10)
mcl_potions.give_effect("withering", objs[n], 2, 10)
end
if hit_some then
mcl_mobs.effect(pos, 32, "mcl_particles_soul_fire_flame.png", 5, 10, self.reach, 1, 0)
@ -469,7 +469,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", {
-- direct hit
hit_player = function(self, player)
local pos = vector.new(self.object:get_pos())
mcl_mobs.effect_functions["withering"](player, 0.5, 10)
mcl_potions.give_effect("withering", player, 2, 10)
player:punch(self.object, 1.0, {
full_punch_interval = 0.5,
damage_groups = {fleshy = 8},
@ -484,7 +484,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", {
hit_mob = function(self, mob)
local pos = vector.new(self.object:get_pos())
mcl_mobs.effect_functions["withering"](mob, 0.5, 10)
mcl_potions.give_effect("withering", mob, 2, 10)
mob:punch(self.object, 1.0, {
full_punch_interval = 0.5,
damage_groups = {fleshy = 8},
@ -522,7 +522,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull_strong", {
-- direct hit
hit_player = function(self, player)
local pos = vector.new(self.object:get_pos())
mcl_mobs.effect_functions["withering"](player, 0.5, 10)
mcl_potions.give_effect("withering", player, 2, 10)
player:punch(self.object, 1.0, {
full_punch_interval = 0.5,
damage_groups = {fleshy = 12},
@ -541,7 +541,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull_strong", {
hit_mob = function(self, mob)
local pos = vector.new(self.object:get_pos())
mcl_mobs.effect_functions["withering"](mob, 0.5, 10)
mcl_potions.give_effect("withering", mob, 2, 10)
mob:punch(self.object, 1.0, {
full_punch_interval = 0.5,
damage_groups = {fleshy = 12},

View File

@ -104,11 +104,11 @@ function mcl_raids.promote_to_raidcaptain(c) -- object
mcl_raids.drop_obanner(pos)
if cmi_cause and cmi_cause.type == "punch" and cmi_cause.puncher:is_player() then
awards.unlock(cmi_cause.puncher:get_player_name(), "mcl:voluntary_exile")
local lv = mcl_potions.player_get_effect(cmi_cause.puncher, "bad_omen")
local lv = mcl_potions.get_effect_level(cmi_cause.puncher, "bad_omen")
if not lv then lv = 0
else lv = lv.factor end
lv = math.max(5,lv + 1)
mcl_potions.bad_omen_func(cmi_cause.puncher,lv,6000)
mcl_potions.give_effect_by_level("bad_omen", cmi_cause.puncher, lv, 6000)
end
end
if old_ondie then return old_ondie(self,pos,cmi_cause) end
@ -296,7 +296,7 @@ mcl_events.register_event("raid",{
--minetest.log("Cond start raid")
local r = {}
for _,p in pairs(minetest.get_connected_players()) do
if mcl_potions.player_has_effect(p,"bad_omen") then
if mcl_potions.has_effect(p,"bad_omen") then
local raid_pos = mcl_raids.find_village(p:get_pos())
if raid_pos then
--minetest.log("We have a raid position. Start raid")
@ -310,7 +310,7 @@ mcl_events.register_event("raid",{
self.mobs = {}
self.health_max = 1
self.health = 0
local lv = mcl_potions.player_get_effect(minetest.get_player_by_name(self.player), "bad_omen")
local lv = mcl_potions.get_effect_level(minetest.get_player_by_name(self.player), "bad_omen")
if lv and lv.factor and lv.factor > 1 then self.max_stage = 6 end
end,
cond_progress = function(self)
@ -331,7 +331,7 @@ mcl_events.register_event("raid",{
end,
on_complete = function(self)
awards.unlock(self.player,"mcl:hero_of_the_village")
mcl_potions.player_clear_effect(minetest.get_player_by_name(self.player),"bad_omen")
mcl_potions.clear_effect(minetest.get_player_by_name(self.player),"bad_omen")
make_firework(self.pos,os.time())
end,
})

View File

@ -120,8 +120,13 @@ mcl_weather.skycolor = {
override_day_night_ratio = function(player, ratio)
local meta = player:get_meta()
local has_night_vision = meta:get_int("night_vision") == 1
local has_darkness = meta:get_int("darkness") == 1
local is_visited_shepherd = meta:get_int("mcl_shepherd:special") == 1
local arg
if has_darkness and not is_visited_shepherd then
if has_night_vision then arg = 0.1
else arg = 0 end
else
-- Apply night vision only for dark sky
local is_dark = minetest.get_timeofday() > 0.8 or minetest.get_timeofday() < 0.2 or mcl_weather.state ~= "none"
local pos = player:get_pos()
@ -135,6 +140,7 @@ mcl_weather.skycolor = {
else
arg = ratio
end
end
player:override_day_night_ratio(arg)
end,

View File

@ -45,4 +45,4 @@ Durability: @1=Wytrzymałość: @1
Block breaking strength: @1=Siła niszczenia bloku: @1
@1 uses=@1 użyć
Unlimited uses=Nielimitowane użycia
...stacks=...kumuluje się

View File

@ -45,3 +45,4 @@ Block breaking strength: @1=
@1 uses=
Unlimited uses=
Durability: @1=
...stacks=

View File

@ -1,4 +1,4 @@
name = mcl_tt
author = Wuzzy
description = Add MCL2 tooltips
depends = tt, mcl_enchanting, mcl_colors
depends = tt, mcl_enchanting, mcl_colors, mcl_util

View File

@ -121,3 +121,58 @@ tt.register_snippet(function(itemstring, _, itemstack)
return S("Durability: @1", S("@1 uses", remaining_use .."/".. use))
end
end)
-- Potions info
tt.register_snippet(function(itemstring, _, itemstack)
if not itemstack then return end
local def = itemstack:get_definition()
if def.groups._mcl_potion ~= 1 then return end
local s = ""
local meta = itemstack:get_meta()
local potency = meta:get_int("mcl_potions:potion_potent")
local plus = meta:get_int("mcl_potions:potion_plus")
local sl_factor = 1
if def.groups.splash_potion == 1 then
sl_factor = mcl_potions.SPLASH_FACTOR
elseif def.groups.ling_potion == 1 then
sl_factor = mcl_potions.LINGERING_FACTOR
end
if def._dynamic_tt then s = s.. def._dynamic_tt((potency+1)*sl_factor).. "\n" end
local effects = def._effect_list
if effects then
local effect
local dur
local timestamp
local ef_level
local roman_lvl
local factor
local ef_tt
for name, details in pairs(effects) do
effect = mcl_potions.registered_effects[name]
if details.dur_variable then
dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, plus) * sl_factor
if potency > 0 and details.uses_level then
dur = dur / math.pow(mcl_potions.POTENT_FACTOR, potency)
end
else
dur = details.dur
end
timestamp = math.floor(dur/60)..string.format(":%02d",math.floor(dur % 60))
if details.uses_level then
ef_level = details.level + details.level_scaling * (potency)
else
ef_level = details.level
end
if ef_level > 1 then roman_lvl = " ".. mcl_util.to_roman(ef_level)
else roman_lvl = "" end
s = s.. effect.description.. roman_lvl.. " (".. timestamp.. ")\n"
if effect.uses_factor then factor = effect.level_to_factor(ef_level) end
if effect.get_tt then ef_tt = minetest.colorize("grey", effect.get_tt(factor)) else ef_tt = "" end
if ef_tt ~= "" then s = s.. ef_tt.. "\n" end
if details.effect_stacks then s = s.. minetest.colorize("grey", S("...stacks")).. "\n" end
end
end
return s:trim()
end)

View File

@ -74,6 +74,22 @@ function tt.reload_itemstack_description(itemstack)
local orig_desc = def._tt_original_description or def.description
if meta:get_string("name") ~= "" then
orig_desc = minetest.colorize(tt.NAME_COLOR, meta:get_string("name"))
elseif def.groups._mcl_potion == 1 then
local potency = meta:get_int("mcl_potions:potion_potent")
local plus = meta:get_int("mcl_potions:potion_plus")
if potency > 0 then
local sym_potency = mcl_util.to_roman(potency+1)
orig_desc = orig_desc.. " ".. sym_potency
end
if plus > 0 then
local sym_plus = " "
local i = plus
while i>0 do
i = i - 1
sym_plus = sym_plus.. "+"
end
orig_desc = orig_desc.. sym_plus
end
end
local desc = apply_snippets(orig_desc, itemstring, toolcaps or def.tool_capabilities, itemstack)
if desc == def.description and meta:get_string("description") == "" then return end

View File

@ -1,4 +1,4 @@
name = tt
author = Wuzzy
description = Support for custom tooltip extensions for items
depends = mcl_colors
depends = mcl_colors, mcl_util

View File

@ -521,7 +521,9 @@ end
local function update_health(player)
local hp_max = player:get_properties().hp_max
hb.change_hudbar(player, "health", player:get_hp(), hp_max)
local hp = player:get_hp()
if hp > hp_max then hp = hp_max end
hb.change_hudbar(player, "health", hp, hp_max)
end
-- update built-in HUD bars

0
mods/HUD/mcl_achievements/init.lua Executable file → Normal file
View File

View File

@ -14,7 +14,7 @@ minetest.register_entity("mcl_experience:bottle",{
local n = node.name
if n ~= "air" and n ~= "mcl_portals:portal" and n ~= "mcl_portals:portal_end" and minetest.get_item_group(n, "liquid") == 0 then
minetest.sound_play("mcl_potions_breaking_glass", {pos = pos, max_hear_distance = 16, gain = 1})
mcl_experience.throw_xp(pos, math.random(3, 11))
mcl_experience.throw_xp(pos, math.random(3, 11) + (self._luck or 0))
minetest.add_particlespawner({
amount = 50,
time = 0.1,
@ -40,13 +40,18 @@ minetest.register_entity("mcl_experience:bottle",{
end,
})
local function throw_xp_bottle(pos, dir, velocity)
local function throw_xp_bottle(pos, dir, velocity, user)
minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true)
local obj = minetest.add_entity(pos, "mcl_experience:bottle")
obj:set_velocity(vector.multiply(dir, velocity))
local acceleration = vector.multiply(dir, -3)
acceleration.y = -9.81
obj:set_acceleration(acceleration)
if user then
local ent = obj:get_luaentity()
local luck = mcl_luck.get_luck(user:get_player_name())
ent._luck = luck
end
end
minetest.register_craftitem("mcl_experience:bottle", {
@ -55,7 +60,7 @@ minetest.register_craftitem("mcl_experience:bottle", {
wield_image = "mcl_experience_bottle.png",
stack_max = 64,
on_use = function(itemstack, placer, pointed_thing)
throw_xp_bottle(vector.add(placer:get_pos(), vector.new(0, 1.5, 0)), placer:get_look_dir(), 10)
throw_xp_bottle(vector.add(placer:get_pos(), vector.new(0, 1.5, 0)), placer:get_look_dir(), 10, placer)
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end

View File

@ -1,4 +1,4 @@
name = mcl_experience
author = oilboi
description = eXPerience mod
depends = mcl_gamemode
depends = mcl_gamemode, mcl_luck

View File

@ -105,7 +105,13 @@ minetest.register_on_mods_loaded(function()
nonmisc = true
end
if def.groups.brewitem then
table.insert(inventory_lists["brew"], name)
local str = name
if def.groups._mcl_potion == 1 then
local stack = ItemStack(name)
tt.reload_itemstack_description(stack)
str = stack:to_string()
end
table.insert(inventory_lists["brew"], str)
nonmisc = true
end
if def.groups.craftitem then
@ -117,6 +123,23 @@ minetest.register_on_mods_loaded(function()
table.insert(inventory_lists["misc"], name)
end
if def.groups._mcl_potion == 1 then
if def.has_potent then
local stack = ItemStack(name)
local potency = def._default_potent_level - 1
stack:get_meta():set_int("mcl_potions:potion_potent", potency)
tt.reload_itemstack_description(stack)
table.insert(inventory_lists["brew"], stack:to_string())
end
if def.has_plus then
local stack = ItemStack(name)
local extend = def._default_extend_level
stack:get_meta():set_int("mcl_potions:potion_plus", extend)
tt.reload_itemstack_description(stack)
table.insert(inventory_lists["brew"], stack:to_string())
end
end
table.insert(inventory_lists["all"], name)
end
end

View File

@ -2,4 +2,4 @@ name = mcl_inventory
author = BlockMen
description = Adds the player inventory and creative inventory.
depends = mcl_init, mcl_formspec, mcl_enchanting, mcl_gamemode
optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide, mcl_player
optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide, mcl_player, tt

View File

@ -4,8 +4,12 @@ there are strings in meta, which are being used to see which effect will be give
Valid strings:
swiftness
leaping
strenght
strength
regeneration
haste
resistance
slow_falling
absorption
]]--
mcl_beacons = {
@ -122,10 +126,17 @@ local formspec_string=
"image[1,4.5;1,1;custom_beacom_symbol_2.png]"..
"image[1,6;1,1;custom_beacom_symbol_1.png]"..
"image_button[5.2,1.5;1,1;mcl_potions_effect_swift.png;swiftness;]"..
"image_button[5.2,1.5;1,1;mcl_potions_effect_swiftness.png;swiftness;]"..
"image_button[8.5,1.5;1,1;mcl_potions_effect_haste.png;haste;]"..
"image_button[5.2,3;1,1;mcl_potions_effect_leaping.png;leaping;]"..
"image_button[5.2,4.5;1,1;mcl_potions_effect_strong.png;strenght;]"..
"image_button[5.2,6;1,1;mcl_potions_effect_regenerating.png;regeneration;]"..
"image_button[8.5,3;1,1;mcl_potions_effect_resistance.png;resistance;]"..
"image_button[5.2,4.5;1,1;mcl_potions_effect_strength.png;strength;]"..
"image_button[8.5,4.5;1,1;mcl_potions_effect_absorption.png;absorption;]"..
"image_button[5.2,6;1,1;mcl_potions_effect_regeneration.png;regeneration;]"..
"image_button[8.5,6;1,1;mcl_potions_effect_slow_falling.png;slow_falling;]"..
"item_image[1,7;1,1;mcl_core:diamond]"..
"item_image[2.2,7;1,1;mcl_core:emerald]"..
@ -197,15 +208,7 @@ end
local function effect_player(effect,pos,power_level, effect_level,player)
local distance = vector.distance(player:get_pos(), pos)
if distance > (power_level+1)*10 then return end
if effect == "swiftness" then
mcl_potions.swiftness_func(player,effect_level,16)
elseif effect == "leaping" then
mcl_potions.leaping_func(player, effect_level, 16)
elseif effect == "strenght" then
mcl_potions.strength_func(player, effect_level, 16)
elseif effect == "regeneration" then
mcl_potions.regeneration_func(player, effect_level, 16)
end
mcl_potions.give_effect_by_level(effect, player, effect_level, 16)
end
local function apply_effects_to_all_players(pos)
@ -254,7 +257,8 @@ minetest.register_node("mcl_beacons:beacon", {
remove_beacon_beam(pos)
end,
on_receive_fields = function(pos, formname, fields, sender)
if fields.swiftness or fields.regeneration or fields.leaping or fields.strenght then
if fields.swiftness or fields.regeneration or fields.leaping or fields.strenght
or fields.haste or fields.resistance or fields.absorption or fields.slow_falling then
local sender_name = sender:get_player_name()
local power_level = beacon_blockcheck(pos)
if minetest.is_protected(pos, sender_name) then
@ -293,6 +297,14 @@ minetest.register_node("mcl_beacons:beacon", {
end
minetest.get_meta(pos):set_string("effect","swiftness")
successful = true
elseif fields.haste then
if power_level == 4 then
minetest.get_meta(pos):set_int("effect_level",2)
else
minetest.get_meta(pos):set_int("effect_level",1)
end
minetest.get_meta(pos):set_string("effect","haste")
successful = true
elseif fields.leaping and power_level >= 2 then
if power_level == 4 then
minetest.get_meta(pos):set_int("effect_level",2)
@ -301,18 +313,38 @@ minetest.register_node("mcl_beacons:beacon", {
end
minetest.get_meta(pos):set_string("effect","leaping")
successful = true
elseif fields.resistance and power_level >= 2 then
if power_level == 4 then
minetest.get_meta(pos):set_int("effect_level",2)
else
minetest.get_meta(pos):set_int("effect_level",1)
end
minetest.get_meta(pos):set_string("effect","resistance")
successful = true
elseif fields.strenght and power_level >= 3 then
if power_level == 4 then
minetest.get_meta(pos):set_int("effect_level",2)
else
minetest.get_meta(pos):set_int("effect_level",1)
end
minetest.get_meta(pos):set_string("effect","strenght")
minetest.get_meta(pos):set_string("effect","strength")
successful = true
elseif fields.absorption and power_level >= 3 then
if power_level == 4 then
minetest.get_meta(pos):set_int("effect_level",2)
else
minetest.get_meta(pos):set_int("effect_level",1)
end
minetest.get_meta(pos):set_string("effect","absorption")
successful = true
elseif fields.regeneration and power_level == 4 then
minetest.get_meta(pos):set_int("effect_level",2)
minetest.get_meta(pos):set_string("effect","regeneration")
successful = true
elseif fields.slow_falling and power_level == 4 then
minetest.get_meta(pos):set_int("effect_level",2)
minetest.get_meta(pos):set_string("effect","slow_falling")
successful = true
end
if successful then
if power_level == 4 then

View File

@ -270,10 +270,10 @@ controls.register_on_release(function(player, key, time)
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
local r = math.random(1,5) + mcl_luck.get_luck(player:get_player_name())
if r > 4 then
-- 20% chance for critical hit (by default)
damage = 10 + math.floor((r-5)/5) -- mega crit (over crit) with high luck
is_critical = true
else
damage = 9

View File

@ -322,10 +322,10 @@ controls.register_on_press(function(player, key, time)
-- Fully charged
local is_critical = false
speed = BOW_MAX_SPEED
local r = math.random(1,5)
if r == 1 then
-- 20% chance for critical hit
damage = 10
local r = math.random(1,5) + mcl_luck.get_luck(player:get_player_name())
if r > 4 then
-- 20% chance for critical hit (by default)
damage = 10 + math.floor((r-5)/5) -- mega crit (over crit) with high luck
is_critical = true
else
damage = 9

View File

@ -1,6 +1,6 @@
name = mcl_bows
author = Arcelmi
description = This mod adds bows and arrows for MineClone 2.
depends = controls, mcl_particles, mcl_enchanting, mcl_init, mcl_util, mcl_shields, mcl_fovapi
depends = controls, mcl_particles, mcl_enchanting, mcl_init, mcl_util, mcl_shields, mcl_fovapi, mcl_luck
optional_depends = awards, mcl_achievements, mcl_core, mcl_mobitems, playerphysics, doc, doc_identifier, mesecons_button

View File

@ -82,7 +82,7 @@ local function brewable(inv)
for i=1,stand_size do
bottle = inv:get_stack("stand", i):get_name()
bottle = inv:get_stack("stand", i)
alchemy = mcl_potions.get_alchemy(ingredient, bottle)
if alchemy then

View File

@ -380,7 +380,7 @@ minetest.register_globalstep(function(dtime)
etime = 0
for _,pl in pairs(minetest.get_connected_players()) do
local armor_feet = pl:get_inventory():get_stack("armor", 5)
if pl and pl:get_player_control().sneak or (minetest.global_exists("mcl_enchanting") and mcl_enchanting.has_enchantment(armor_feet, "frost_walker")) or (minetest.global_exists("mcl_potions") and mcl_potions.player_has_effect(pl, "fire_proof")) then
if pl and pl:get_player_control().sneak or (minetest.global_exists("mcl_enchanting") and mcl_enchanting.has_enchantment(armor_feet, "frost_walker")) or (minetest.global_exists("mcl_potions") and mcl_potions.has_effect(pl, "fire_resistance")) then
return
end
burn_in_campfire(pl)

View File

@ -167,17 +167,17 @@ local function eat_gapple(itemstack, placer, pointed_thing)
return itemstack
end
local regen_duration, absorbtion_factor = 5, 1
local regen_duration, absorption = 5, 1
if itemstack:get_name() == "mcl_core:apple_gold_enchanted" then
regen_duration, absorbtion_factor = 20, 4
mcl_potions.fire_resistance_func(placer, 1, 300)
mcl_potions.leaping_func(placer, 1, 300)
regen_duration, absorption = 20, 4
mcl_potions.give_effect("fire_resistance", placer, 1, 300)
mcl_potions.give_effect_by_level("leaping", placer, 1, 300)
if enable_fapples then
mcl_potions.swiftness_func(placer, absorbtion_factor, 120)
mcl_potions.give_effect_by_level("swiftness", placer, absorption, 120)
end
end
-- TODO: Absorbtion
mcl_potions.regeneration_func(placer, 2, regen_duration)
mcl_potions.give_effect_by_level("absorption", placer, absorption, 120)
mcl_potions.give_effect_by_level("regeneration", placer, 2, regen_duration)
return gapple_hunger_restore(itemstack, placer, pointed_thing)
end
@ -206,17 +206,17 @@ local function eat_gapple_delayed(itemstack, placer, pointed_thing)
return itemstack
end
local regen_duration, absorbtion_factor = 5, 1
local regen_duration, absorption = 5, 1
if itemstack:get_name() == "mcl_core:apple_gold_enchanted" then
regen_duration, absorbtion_factor = 20, 4
mcl_potions.fire_resistance_func(placer, 1, 300)
mcl_potions.leaping_func(placer, 1, 300)
regen_duration, absorption = 20, 4
mcl_potions.give_effect("fire_resistance", placer, 1, 300)
mcl_potions.give_effect_by_level("leaping", placer, 1, 300)
if enable_fapples then
mcl_potions.swiftness_func(placer, absorbtion_factor, 120)
mcl_potions.give_effect_by_level("swiftness", placer, absorption, 120)
end
end
-- TODO: Absorbtion
mcl_potions.regeneration_func(placer, 2, regen_duration)
mcl_potions.give_effect_by_level("absorption", placer, absorption, 120)
mcl_potions.give_effect_by_level("regeneration", placer, 2, regen_duration)
--return gapple_hunger_restore(itemstack, placer, pointed_thing)
end

View File

@ -56,7 +56,7 @@ end
function mcl_enchanting.get_enchantment_description(enchantment, level)
local enchantment_def = mcl_enchanting.enchantments[enchantment]
return enchantment_def.name ..
(enchantment_def.max_level == 1 and "" or " " .. mcl_enchanting.roman_numerals.toRoman(level))
(enchantment_def.max_level == 1 and "" or " " .. mcl_util.to_roman(level))
end
function mcl_enchanting.get_colorized_enchantment_description(enchantment, level)

View File

@ -11,7 +11,6 @@ mcl_enchanting = {
book_animation_steps = {0, 640, 680, 700, 740},
book_animation_loop = {["open"] = true, ["close"] = true},
book_animation_speed = 40,
roman_numerals = dofile(modpath .. "/roman_numerals.lua"), -- https://exercism.io/tracks/lua/exercises/roman-numerals/solutions/73c2fb7521e347209312d115f872fa49
enchantments = {},
overlay = "^[colorize:purple:50",
--overlay = "^[invert:rgb^[multiply:#4df44d:50^[invert:rgb",

View File

@ -1,5 +1,5 @@
name = mcl_enchanting
description = Enchanting for MineClone2
depends = tt, walkover, mcl_sounds, mcl_colors, mcl_experience
depends = tt, walkover, mcl_sounds, mcl_colors, mcl_experience, mcl_util
optional_depends = screwdriver
author = Fleckenstein

View File

@ -1,34 +0,0 @@
--------------------------------------------------------------------
--! @file
--! @brief Convert from normal numbers to Roman Numerals
---------------------------------------------------------------------
local conversionTable = {
{ number = 1000, symbol = "M" },
{ number = 900, symbol = "CM" },
{ number = 500, symbol = "D" },
{ number = 400, symbol = "CD" },
{ number = 100, symbol = "C" },
{ number = 90, symbol = "XC" },
{ number = 50, symbol = "L" },
{ number = 40, symbol = "XL" },
{ number = 10, symbol = "X" },
{ number = 9, symbol = "IX" },
{ number = 5, symbol = "V" },
{ number = 4, symbol = "IV" },
{ number = 1, symbol = "I" }
}
return{
toRoman = function(number)
local romanNumeral = ""
for _,table in pairs (conversionTable) do
while(number >= table.number) do
romanNumeral = romanNumeral .. table.symbol
number = number - table.number
end
end
return romanNumeral
end
}

View File

@ -28,8 +28,8 @@ minetest.register_entity("mcl_end:ender_eye", {
self._age = self._age + dtime
if self._age >= 3 then
-- End of life
local r = math.random(1,5)
if r == 1 then
local r = math.random(1,15) + self._luck
if r <= 3 then
-- 20% chance to get destroyed completely.
-- 100% if in Creative Mode
self.object:remove()
@ -85,11 +85,12 @@ minetest.register_craftitem("mcl_end:ender_eye", {
if user == nil then
return
end
local player_name = user:get_player_name()
local origin = user:get_pos()
origin.y = origin.y + 1.5
local strongholds = mcl_structures.registered_structures["end_shrine"].static_pos
local dim = mcl_worlds.pos_to_dimension(origin)
local is_creative = minetest.is_creative_enabled(user:get_player_name())
local is_creative = minetest.is_creative_enabled(player_name)
-- Just drop the eye of ender if there are no strongholds
if #strongholds <= 0 or dim ~= "overworld" then
@ -124,6 +125,8 @@ minetest.register_craftitem("mcl_end:ender_eye", {
-- Throw it!
local obj = minetest.add_entity(origin, "mcl_end:ender_eye")
local dir
local ent = obj:get_luaentity()
ent._luck = mcl_luck.get_luck(player_name)
if lowest_dist <= 25 then
local velocity = 4

View File

@ -1,2 +1,2 @@
name = mcl_end
depends = screwdriver, mcl_sounds, mcl_util, doc_items, mcl_worlds, mcl_structures, mcl_stonecutter
depends = screwdriver, mcl_sounds, mcl_util, doc_items, mcl_worlds, mcl_structures, mcl_stonecutter, mcl_luck

View File

@ -142,7 +142,7 @@ minetest.register_on_item_eat(function (hp_change, replace_with_item, itemstack,
-- 60% chance of poisoning with poisonous potato
if itemstack:get_name() == "mcl_farming:potato_item_poison" then
if math.random(1,10) >= 6 then
mcl_potions.poison_func(user, 1, 5)
mcl_potions.give_effect_by_level("poison", user, 1, 5)
end
end

View File

@ -62,8 +62,8 @@ local fish = function(itemstack, player, pointed_thing)
local junk_values = {10, 8.1, 6.1, 4.2}
local luck_of_the_sea = math.min(mcl_enchanting.get_enchantment(itemstack, "luck_of_the_sea"), 3)
local index = luck_of_the_sea + 1
local fish_value = fish_values[index]
local junk_value = junk_values[index] + fish_value
local fish_value = fish_values[index] - mcl_luck.get_luck(ent.player)
local junk_value = junk_values[index] + fish_value - mcl_luck.get_luck(ent.player)
if r <= fish_value then
-- Fish
items = mcl_loot.get_loot({
@ -114,6 +114,8 @@ local fish = function(itemstack, player, pointed_thing)
{ itemstring = "mcl_mobitems:saddle", },
{ itemstring = "mcl_flowers:waterlily", },
{ itemstring = "mcl_mobitems:nautilus_shell", },
{ itemstring = "mcl_mobitems:spectre_membrane", },
{ itemstring = "mcl_mobitems:crystalline_drop", },
},
stacks_min = 1,
stacks_max = 1,
@ -519,7 +521,8 @@ minetest.register_craftitem("mcl_fishing:pufferfish_raw", {
minetest.register_on_item_eat(function (hp_change, replace_with_item, itemstack, user, pointed_thing)
if itemstack:get_name() == "mcl_fishing:pufferfish_raw" then
mcl_potions.poison_func(user, 1/3, 60)
mcl_potions.give_effect_by_level("poison", user, 3, 60)
mcl_potions.give_effect_by_level("nausea", user, 2, 20)
end
end )

View File

@ -1,3 +1,3 @@
name = mcl_fishing
description = Adds fish and fishing poles to go fishing.
depends = mcl_core, mcl_sounds, mcl_loot, mcl_mobs, mcl_enchanting, mcl_throwing, mcl_colors, mcl_buckets
depends = mcl_core, mcl_sounds, mcl_loot, mcl_mobs, mcl_enchanting, mcl_throwing, mcl_colors, mcl_buckets, mcl_luck

View File

@ -194,8 +194,8 @@ def_clover.mesh = "mcl_clover_3leaf.obj"
def_clover.tiles = { "mcl_flowers_clover.png" }
def_clover.inventory_image = "mcl_flowers_clover_inv.png"
def_clover.wield_image = "mcl_flowers_clover_inv.png"
def_clover.drop = nil
def_clover.use_texture_alpha = "clip"
def_clover.drop = "mcl_flowers:clover"
def_clover.selection_box = {
type = "fixed",
fixed = { -4/16, -0.5, -4/16, 4/16, 0, 4/16 },
@ -212,6 +212,7 @@ def_4l_clover.tiles = { "mcl_flowers_fourleaf_clover.png" }
def_4l_clover.inventory_image = "mcl_flowers_fourleaf_clover_inv.png"
def_4l_clover.wield_image = "mcl_flowers_fourleaf_clover_inv.png"
def_4l_clover.use_texture_alpha = "clip"
def_4l_clover.drop = "mcl_flowers:fourleaf_clover"
minetest.register_node("mcl_flowers:fourleaf_clover", def_4l_clover)

View File

@ -154,7 +154,7 @@ local function drink_milk_delayed(itemstack, player, pointed_thing)
) then
mcl_hunger.stop_poison(player)
end
mcl_potions._reset_player_effects(player)
mcl_potions._reset_effects(player)
end
-- Wrapper for handling mcl_hunger delayed eating
@ -231,6 +231,46 @@ minetest.register_craftitem("mcl_mobitems:string",{
groups = { craftitem = 1 },
})
minetest.register_craftitem("mcl_mobitems:spectre_membrane",{
description = S("Spectre Membrane"),
_doc_items_longdesc = S("This is a crafting component dropped from dead spectres."),
inventory_image = "vl_mobitems_spectre_membrane.png",
groups = { craftitem = 1, brewitem = 1 },
stack_max = 64,
})
minetest.register_craftitem("mcl_mobitems:shiny_ice_crystal",{
description = S("Shiny Ice Crystal"),
_doc_items_longdesc = S("This item is mainly used for crafting."),
inventory_image = "vl_mobitems_ice_crystal.png",
groups = { craftitem = 1, brewitem = 1 },
stack_max = 64,
})
minetest.register_craftitem("mcl_mobitems:aery_charge",{
description = S("Aery Charge"),
_doc_items_longdesc = S("This item is mainly used for crafting."), -- TODO shoot?
inventory_image = "vl_mobitems_aery_charge.png",
groups = { craftitem = 1, brewitem = 1 },
stack_max = 64,
})
minetest.register_craftitem("mcl_mobitems:crystalline_drop",{
description = S("Crystalline Drop"),
_doc_items_longdesc = S("This item is mainly used for crafting."), -- TODO other uses?
inventory_image = "vl_mobitems_crystalline_drop.png",
groups = { craftitem = 1, brewitem = 1 },
stack_max = 64,
})
minetest.register_craftitem("mcl_mobitems:earthen_ash",{
description = S("Earthen Ash"),
_doc_items_longdesc = S("This item is mainly used for crafting."), -- TODO other uses?
inventory_image = "vl_mobitems_earthen_ash.png",
groups = { craftitem = 1, brewitem = 1 },
stack_max = 64,
})
minetest.register_craftitem("mcl_mobitems:blaze_rod", {
description = S("Blaze Rod"),
_doc_items_longdesc = S("This is a crafting component dropped from dead blazes."),
@ -580,6 +620,6 @@ minetest.register_craft({
minetest.register_on_item_eat(function (hp_change, replace_with_item, itemstack, user, pointed_thing) -- poisoning with spider eye
if itemstack:get_name() == "mcl_mobitems:spider_eye" then
mcl_potions.poison_func(user, 1, 4)
mcl_potions.give_effect_by_level("poison", user, 1, 4)
end
end)

View File

@ -58,6 +58,12 @@ This item is dropped by dead squids. Squid ink can be used to as an ingredient
String=Nić
Strings are used in crafting.=Nić jest użyteczna w wytwarzaniu.
Spectre Membrane=Błona Widma
This is a crafting component dropped from dead spectres.=Jest to materiał do wytwarzania wypadający z martwych widm.
Shiny Ice Crystal=Lśniący Kryształ Lodu
Aery Charge=Powietrzny Ładunek
Crystalline Drop=Krystaliczna Kropla
Earthen Ash=Ziemny Popiół
Blaze Rod=Płomienna różdżka
This is a crafting component dropped from dead blazes.=Jest to materiał do wytwarzania wypadający z martwych płomyków.
Blaze Powder=Płomienny proszek

View File

@ -135,7 +135,7 @@ minetest.register_node("mcl_nether:magma", {
-- From walkover mod
on_walk_over = function(loc, nodeiamon, player)
local armor_feet = player:get_inventory():get_stack("armor", 5)
if player and player:get_player_control().sneak or (minetest.global_exists("mcl_enchanting") and mcl_enchanting.has_enchantment(armor_feet, "frost_walker")) or (minetest.global_exists("mcl_potions") and mcl_potions.player_has_effect(player, "fire_proof")) then
if player and player:get_player_control().sneak or (minetest.global_exists("mcl_enchanting") and mcl_enchanting.has_enchantment(armor_feet, "frost_walker")) or (minetest.global_exists("mcl_potions") and mcl_potions.has_effect(player, "fire_resistance")) then
return
end
-- Hurt players standing on top of this block

View File

@ -0,0 +1,318 @@
## Potions and Effects API
<!-- TOC -->
* [Potions and Effects API](#potions-and-effects-api)
* [Namespace](#namespace)
* [Effects](#effects)
* [Functions](#functions)
* [Deprecated Functions](#deprecated-functions)
* [Tables](#tables)
* [Internally registered effects](#internally-registered-effects)
* [Constants](#constants)
* [Effect Definition](#effect-definition)
* [HP Hudbar Modifiers](#hp-hudbar-modifiers)
* [Functions](#functions)
* [HP Hudbar Modifier Definition](#hp-hudbar-modifier-definition)
* [Potions](#potions)
* [Functions](#functions)
* [Tables](#tables)
* [Internally registered potions](#internally-registered-potions)
* [Constants](#constants)
* [Potion Definition](#potion-definition)
* [Brewing](#brewing)
* [Functions](#functions)
* [Miscellaneous Functions](#miscellaneous-functions)
<!-- TOC -->
### Namespace
All of the API is defined in the `mcl_potions` namespace.
### Effects
This section describes parts of the API related to defining and managing effects on players and entities. The mod defines a bunch of effects internally using the same API as described below.
#### Functions
`mcl_potions.register_effect(def)` takes an effect definition (`def`) and registers an effect if the definition is valid, and adds the known parts of the definition as well as the outcomes of processing of some parts of the definition to the `mcl_potions.registered_effects` table. This should only be used at load time.
`mcl_potions.apply_haste_fatigue(toolcaps, h_fac, f_fac)` takes a table of tool capabilities (`toolcaps`) and modifies it using the provided haste factor (`h_fac`) and fatigue factor (`f_fac`). The factors default to no-op values.
`mcl_potions.hf_update_internal(hand, object)` returns the `hand` of the `object` updated according to their combined haste and fatigue. **This doesn't change anything by itself!** Manual update of the hand with the hand returned by this function has to be done. This should only be called in situations that are *directly* impacted by haste and/or fatigue, and therefore require an update of the hand.
`mcl_potions.update_haste_and_fatigue(player)` updates haste and fatigue on a `player` (described by an ObjectRef). This should be called whenever an update of the haste-type and fatigue-type effects is desired.
`mcl_potions._reset_haste_fatigue_item_meta(player)` resets the item meta changes caused by haste-type and fatigue-type effects throughout the inventory of the `player` described by an ObjectRef.
`mcl_potions._clear_cached_effect_data(object)` clears cashed effect data for the `object`. This shouldn't be used for resetting effects.
`mcl_potions._reset_effects(object, set_hud)` actually resets the effects for the `object`. It also updates HUD if `set_hud` is `true` or undefined (`nil`).
`mcl_potions._save_player_effects(player)` saves all effects of the `player` described by an ObjectRef to metadata.
`mcl_potions._load_player_effects(player)` loads all effects from the metadata of the `player` described by an ObjectRef.
`mcl_potions._load_entity_effects(entity)` loads all effects from the `entity` (a LuaEntity).
`mcl_potions.has_effect(object, effect_name)` returns `true` if `object` (described by an ObjectRef) has the effect of the ID `effect_name`, `false` otherwise.
`mcl_potions.get_effect(object, effect_name)` - returns a table containing values of the effect of the ID `effect_name` on the `object` if the object has the named effect, `false` otherwise.
`mcl_potions.get_effect_level(object, effect_name)` returns the level of the effect of the ID `effect_name` on the `object`. If the effect has no levels, returns `1`. If the object doesn't have the effect, returns `0`. If the effect is not registered, returns `nil`.
`mcl_potions.get_total_haste(object)` returns the total haste of the `object` (from all haste-type effects).
`mcl_potions.get_total_fatigue(object)` returns the total fatigue of the `object` (from all fatigue-type effects).
`mcl_potions.clear_effect(object, effect)` attempts to remove the effect of the ID `effect` from the `object`. If the effect is not registered, logs a warning and returns `false`. Otherwise, returns `nil`.
`mcl_potions.make_invisible(obj_ref, hide)` makes the object going by the `obj_ref` invisible if `hide` is true, visible otherwise.
`mcl_potions.register_generic_resistance_predicate(predicate)`  registers an arbitrary effect resistance predicate. This can be used e.g. to make some entity resistant to all (or some) effects under specific conditions.
* `predicate` `function(object, effect_name)` - return `true` if `object` resists effect of the ID `effect_name`
`mcl_potions.give_effect(name, object, factor, duration, no_particles)` attempts to give effect of the ID `name` to the `object` with the provided `factor` and `duration`. If `no_particles` is `true`, no particles will be emitted from the object when under the effect. If the effect is not registered, target is invalid (or resistant), or the same effect with more potency is already applied to the target, this function does nothing and returns `false`. On success, this returns `true`.
`mcl_potions.give_effect_by_level(name, object, level, duration, no_particles)` attempts to give effect of the ID `name` to the `object` with the provided `level` and `duration`. If `no_particles` is `true`, no particles will be emitted from the object when under the effect. This converts `level` to factor and calls `mcl_potions.give_effect()` internally, returning the return value of that function. `level` equal to `0` is no-op.
`mcl_potions.healing_func(object, hp)` attempts to heal the `object` by `hp`. Negative `hp` harms magically instead.
#### Deprecated functions
**Don't use the following functions, use the above API instead!** The following are only provided for backwards compatibility and will be removed later. They all call `mcl_potions.give_effect()` internally.
* `mcl_potions.strength_func(object, factor, duration)`
* `mcl_potions.leaping_func(object, factor, duration)`
* `mcl_potions.weakness_func(object, factor, duration)`
* `mcl_potions.swiftness_func(object, factor, duration)`
* `mcl_potions.slowness_func(object, factor, duration)`
* `mcl_potions.withering_func(object, factor, duration)`
* `mcl_potions.poison_func(object, factor, duration)`
* `mcl_potions.regeneration_func(object, factor, duration)`
* `mcl_potions.invisiblility_func(object, null, duration)`
* `mcl_potions.water_breathing_func(object, null, duration)`
* `mcl_potions.fire_resistance_func(object, null, duration)`
* `mcl_potions.night_vision_func(object, null, duration)`
* `mcl_potions.bad_omen_func(object, factor, duration)`
#### Tables
`mcl_potions.registered_effects` contains all effects that have been registered. You can read from it various data about the effects. You can overwrite the data and alter the effects' definitions too, but this is discouraged, i.e. only do this if you really know what you are doing. You shouldn't add effects directly to this table, as this would skip important setup; instead use the `mcl_potions.register_effect()` function, which is described above.
#### Internally registered effects
You can't register effects going by these names, because they are already used:
* `invisibility`
* `poison`
* `regeneration`
* `strength`
* `weakness`
* `weakness`
* `dolphin_grace`
* `leaping`
* `slow_falling`
* `swiftness`
* `slowness`
* `levitation`
* `night_vision`
* `darkness`
* `glowing`
* `health_boost`
* `absorption`
* `fire_resistance`
* `resistance`
* `luck`
* `bad_luck`
* `bad_omen`
* `hero_of_village`
* `withering`
* `frost`
* `blindness`
* `nausea`
* `food_poisoning`
* `saturation`
* `haste`
* `fatigue`
* `conduit_power`
#### Constants
`mcl_potions.LONGEST_MINING_TIME` longest mining time of one block that can be achieved by slowing down the mining by fatigue-type effects.
`mcl_potions.LONGEST_PUNCH_INTERVAL` longest punch interval that can be achieved by slowing down the punching by fatigue-type effects.
#### Effect Definition
```lua
def = {
-- required parameters in def:
name = string -- effect name in code (unique ID) - can't be one of the reserved words ("list", "heal", "remove", "clear")
description = S(string) -- actual effect name in game
-- optional parameters in def:
get_tt = function(factor) -- returns tooltip description text for use with potions
icon = string -- file name of the effect icon in HUD - defaults to one based on name
res_condition = function(object) -- returning true if target is to be resistant to the effect
on_start = function(object, factor) -- called when dealing the effect
on_load = function(object, factor) -- called on_joinplayer and on_activate
on_step = function(dtime, object, factor, duration) -- running every step for all objects with this effect
on_hit_timer = function(object, factor, duration) -- if defined runs a hit_timer depending on timer_uses_factor value
on_end = function(object) -- called when the effect wears off
after_end = function(object) -- called when the effect wears off, after purging the data of the effect
on_save_effect = function(object -- called when the effect is to be serialized for saving (supposed to do cleanup)
particle_color = string -- colorstring for particles - defaults to #3000EE
uses_factor = bool -- whether factor affects the effect
lvl1_factor = number -- factor for lvl1 effect - defaults to 1 if uses_factor
lvl2_factor = number -- factor for lvl2 effect - defaults to 2 if uses_factor
timer_uses_factor = bool -- whether hit_timer uses factor (uses_factor must be true) or a constant value (hit_timer_step must be defined)
hit_timer_step = float -- interval between hit_timer hits
damage_modifier = string -- damage flag of which damage is changed as defined by modifier_func, pass empty string for all damage
dmg_mod_is_type = bool -- damage_modifier string is used as type instead of flag of damage, defaults to false
modifier_func = function(damage, effect_vals) -- see damage_modifier, if not defined damage_modifier defaults to 100% resistance
modifier_priority = integer -- priority passed when registering damage_modifier - defaults to -50
affects_item_speed = table
-- -- if provided, effect gets added to the item_speed_effects table, this should be true if the effect affects item speeds,
-- -- otherwise it won't work properly with other such effects (like haste and fatigue)
-- -- -- factor_is_positive - bool - whether values of factor between 0 and 1 should be considered +factor% or speed multiplier
-- -- -- - obviously +factor% is positive and speed multiplier is negative interpretation
-- -- -- - values of factor higher than 1 will have a positive effect regardless
-- -- -- - values of factor lower than 0 will have a negative effect regardless
}
```
### HP Hudbar Modifiers
This part of the API allows complex modification of the HP hudbar. It is mainly required here, so it is defined here. It may be moved to a different mod in the future.
#### Functions
`mcl_potions.register_hp_hudbar_modifier(def)` this function takes a modifier definition (`def`, described below) and registers a HP hudbar modifier if the definition is valid.
#### HP Hudbar Modifier Definition
```lua
def = {
-- required parameters in def:
predicate = function(player) -- returns true if player fulfills the requirements (eg. has the effects) for the hudbar look
icon = string -- name of the icon to which the modifier should change the HP hudbar heart
priority = signed_int -- lower gets checked first, and first fulfilled predicate applies its modifier
}
```
### Potions
Magic!
#### Functions
`mcl_potions.register_potion(def)` takes a potion definition (`def`) and registers a potion if the definition is valid, and adds the known parts of the definition as well as the outcomes of processing of some parts of the definition to the `mcl_potions.registered_effects` table. This, depending on some fields of the definition, may as well register the corresponding splash potion, lingering potion and tipped arrow. This should only be used at load time.
`mcl_potions.register_splash(name, descr, color, def)` registers a splash potion (item and entity when thrown). This is mostly part of the internal API and probably shouldn't be used from outside, therefore not providing exact description. This is used by `mcl_potions.register_potion()`.
`mcl_potions.register_lingering(name, descr, color, def)` registers a lingering potion (item and entity when thrown). This is mostly part of the internal API and probably shouldn't be used from outside, therefore not providing exact description. This is used by `mcl_potions.register_potion()`.
`mcl_potions.register_arrow(name, desc, color, def)` registers a tipped arrow (item and entity when shot). This is mostly part of the internal API and probably shouldn't be used from outside, therefore not providing exact description. This is used by `mcl_potions.register_potion()`.
#### Tables
`mcl_potions.registered_potions` contains all potions that have been registered. You can read from it various data about the potions. You can overwrite the data and alter the definitions too, but this is discouraged, i.e. only do this if you really know what you are doing. You shouldn't add potions directly to this table, because they have to be registered as items too; instead use the `mcl_potions.register_potion()` function, which is described above. Some brewing recipes are autofilled based on this table after the loading of all the mods is done.
#### Constants
* `mcl_potions.POTENT_FACTOR = 2`
* `mcl_potions.PLUS_FACTOR = 8/3`
* `mcl_potions.INV_FACTOR = 0.50`
* `mcl_potions.DURATION = 180`
* `mcl_potions.DURATION_INV = mcl_potions.DURATION * mcl_potions.INV_FACTOR`
* `mcl_potions.DURATION_POISON = 45`
* `mcl_potions.II_FACTOR = mcl_potions.POTENT_FACTOR` **DEPRECATED**
* `mcl_potions.DURATION_PLUS = mcl_potions.DURATION * mcl_potions.PLUS_FACTOR` **DEPRECATED**
* `mcl_potions.DURATION_2 = mcl_potions.DURATION / mcl_potions.II_FACTOR` **DEPRECATED**
* `mcl_potions.SPLASH_FACTOR = 0.75`
* `mcl_potions.LINGERING_FACTOR = 0.25`
#### Potion Definition
```lua
def = {
-- required parameters in def:
name = string, -- potion name in code
-- optional parameters in def:
desc_prefix = S(string), -- part of visible potion name, comes before the word "Potion"
desc_suffix = S(string), -- part of visible potion name, comes after the word "Potion"
_tt = S(string), -- custom tooltip text
_dynamic_tt = function(level), -- returns custom tooltip text dependent on potion level
_longdesc = S(string), -- text for in=game documentation
stack_max = int, -- max stack size - defaults to 1
image = string, -- name of a custom texture of the potion icon
color = string, -- colorstring for potion icon when image is not defined - defaults to #0000FF
groups = table, -- item groups definition for the regular potion, not splash or lingering -
-- - must contain _mcl_potion=1 for tooltip to include dynamic_tt and effects
-- - defaults to {brewitem=1, food=3, can_eat_when_full=1, _mcl_potion=1}
nocreative = bool, -- adds a not_in_creative_inventory=1 group - defaults to false
_effect_list = {, -- all the effects dealt by the potion in the format of tables
-- -- the name of each sub-table should be a name of a registered effect, and fields can be the following:
uses_level = bool, -- whether the level of the potion affects the level of the effect -
-- -- -- - defaults to the uses_factor field of the effect definition
level = int, -- used as the effect level if uses_level is false and for lvl1 potions - defaults to 1
level_scaling = int, -- used as the number of effect levels added per potion level - defaults to 1 -
-- -- -- - this has no effect if uses_level is false
dur = float, -- duration of the effect in seconds - defaults to mcl_potions.DURATION
dur_variable = bool, -- whether variants of the potion should have the length of this effect changed -
-- -- -- - defaults to true
-- -- -- - if at least one effect has this set to true, the potion has a "plus" variant
effect_stacks = bool, -- whether the effect stacks - defaults to false
}
uses_level = bool, -- whether the potion should come at different levels -
-- - defaults to true if uses_level is true for at least one effect, else false
drinkable = bool, -- defaults to true
has_splash = bool, -- defaults to true
has_lingering = bool, -- defaults to true
has_arrow = bool, -- defaults to false
has_potent = bool, -- whether there is a potent (e.g. II) variant - defaults to the value of uses_level
default_potent_level = int, -- potion level used for the default potent variant - defaults to 2
default_extend_level = int, -- extention level (amount of +) used for the default extended variant - defaults to 1
custom_on_use = function(user, level), -- called when the potion is drunk, returns true on success
custom_effect = function(object, level, plus), -- called when the potion effects are applied, returns true on success
custom_splash_effect = function(pos, level), -- called when the splash potion explodes, returns true on success
custom_linger_effect = function(pos, radius, level), -- called on the lingering potion step, returns true on success
}
```
### Brewing
Functions supporting brewing potions, used by the `mcl_brewing` module, which calls `mcl_potions.get_alchemy()`.
#### Functions
`mcl_potions.register_ingredient_potion(input, out_table)` registers a potion (`input`, item string) that can be combined with multiple ingredients for different outcomes; `out_table` contains the recipes for those outcomes
`mcl_potions.register_water_brew(ingr, potion)` registers a `potion` (item string) brewed from water with a specific ingredient (`ingr`)
`mcl_potions.register_awkward_brew(ingr, potion)` registers a `potion` (item string) brewed from an awkward potion with a specific ingredient (`ingr`)
`mcl_potions.register_mundane_brew(ingr, potion)` registers a `potion` (item string) brewed from a mundane potion with a specific ingredient (`ingr`)
`mcl_potions.register_thick_brew(ingr, potion)` registers a `potion` (item string) brewed from a thick potion with a specific ingredient (`ingr`)
`mcl_potions.register_table_modifier(ingr, modifier)` registers a brewing recipe altering the potion using a table; this is supposed to substitute one item with another
`mcl_potions.register_inversion_recipe(input, output)` what it says
`mcl_potions.register_meta_modifier(ingr, mod_func)`  registers a brewing recipe altering the potion using a function; this is supposed to be a recipe that changes metadata only
`mcl_potions.get_alchemy(ingr, pot)` finds an alchemical recipe for given ingredient and potion; returns outcome
### Miscellaneous Functions
`mcl_potions._extinguish_nearby_fire(pos, radius)` attempts to extinguish fires in an area, both on objects and nodes.
`mcl_potions._add_spawner(obj, color)` adds a particle spawner denoting an effect being in action.
`mcl_potions._use_potion(obj, color)` visual and sound effects of drinking a potion.
`mcl_potions.is_obj_hit(self, pos)` determines if an object is hit (by a thrown potion).

View File

@ -8,23 +8,9 @@ local S = minetest.get_translator(minetest.get_current_modname())
-- ░╚════╝░╚═╝░░╚═╝╚═╝░░╚═╝░░░╚═╝░░░  ░╚════╝░░╚════╝░╚═╝░░░░░╚═╝╚═╝░░░░░╚═╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░╚═════╝░
local get_chat_function = {}
get_chat_function["poison"] = mcl_potions.poison_func
get_chat_function["regeneration"] = mcl_potions.regeneration_func
get_chat_function["invisibility"] = mcl_potions.invisiblility_func
get_chat_function["fire_resistance"] = mcl_potions.fire_resistance_func
get_chat_function["night_vision"] = mcl_potions.night_vision_func
get_chat_function["water_breathing"] = mcl_potions.water_breathing_func
get_chat_function["leaping"] = mcl_potions.leaping_func
get_chat_function["swiftness"] = mcl_potions.swiftness_func
get_chat_function["heal"] = mcl_potions.healing_func
get_chat_function["bad_omen"] = mcl_potions.bad_omen_func
get_chat_function["withering"] = mcl_potions.withering_func
minetest.register_chatcommand("effect",{
params = S("<effect> <duration> [<factor>]"),
description = S("Add a status effect to yourself. Arguments: <effect>: name of status effect, e.g. poison. <duration>: duration in seconds. <factor>: effect strength multiplier (1 = 100%)"),
params = S("<effect>|heal|list|clear|remove <duration|heal-amount|effect>|INF [<level>] [<factor>] [NOPART]"),
description = S("Add a status effect to yourself. Arguments: <effect>: name of status effect. Passing \"list\" as effect name lists available effects. Passing \"heal\" as effect name heals (or harms) by amount designed by the next parameter. Passing \"clear\" as effect name removes all effects. Passing \"remove\" as effect name removes the effect named by the next parameter. <duration>: duration in seconds. Passing \"INF\" as duration makes the effect infinite. (<heal-amount>: amount of healing when the effect is \"heal\", passing a negative value subtracts health. <effect>: name of a status effect to be removed when using \"remove\" as the previous parameter.) <level>: effect power determinant, bigger level results in more powerful effect for effects that depend on the level (no changes for other effects), defaults to 1, pass F to use low-level factor instead. <factor>: effect strength modifier, can mean different things depending on the effect, no changes for effects that do not depend on level/factor. NOPART at the end means no particles will be shown for this effect."),
privs = {server = true},
func = function(name, params)
@ -37,22 +23,93 @@ minetest.register_chatcommand("effect",{
if not P[1] then
return false, S("Missing effect parameter!")
elseif not tonumber(P[2]) then
return false, S("Missing or invalid duration parameter!")
elseif P[3] and not tonumber(P[3]) then
return false, S("Invalid factor parameter!")
elseif P[1] == "list" then
local effects = "heal"
for effect, _ in pairs(mcl_potions.registered_effects) do
effects = effects .. ", " .. effect
end
-- Default factor = 1
if not P[3] then
P[3] = 1.0
return true, effects
elseif P[1] == "heal" then
local hp = tonumber(P[2])
if not hp or hp == 0 then
return false, S("Missing or invalid heal amount parameter!")
else
mcl_potions.healing_func(minetest.get_player_by_name(name), hp)
if hp > 0 then
if hp < 1 then hp = 1 end
return true, S("Player @1 healed by @2 HP.", name, hp)
else
if hp > -1 then hp = -1 end
return true, S("Player @1 harmed by @2 HP.", name, hp)
end
end
elseif P[1] == "clear" then
mcl_potions._reset_effects(minetest.get_player_by_name(name))
return true, S("Effects cleared for player @1", name)
elseif P[1] == "remove" then
if not P[2] then
return false, S("Missing effect parameter!")
end
if mcl_potions.registered_effects[P[2]] then
mcl_potions.clear_effect(minetest.get_player_by_name(name), P[2])
return true, S("Removed effect @1 from player @2", P[2], name)
else
return false, S("@1 is not an available status effect.", P[2])
end
elseif not tonumber(P[2]) and P[2] ~= "INF" then
return false, S("Missing or invalid duration parameter!")
elseif P[3] and not tonumber(P[3]) and P[3] ~= "F" and P[3] ~= "NOPART" then
return false, S("Invalid level parameter!")
elseif P[3] and P[3] == "F" and not P[4] then
return false, S("Missing or invalid factor parameter when level is F!")
end
if get_chat_function[P[1]] then
get_chat_function[P[1]](minetest.get_player_by_name(name), tonumber(P[3]), tonumber(P[2]))
return true
-- Default level = 1
if not P[3] then
P[3] = 1
elseif P[3] == "NOPART" then
P[3] = 1
P[4] = "NOPART"
end
local inf = P[2] == "INF"
local nopart = false
if P[3] == "F" then
nopart = P[5] == "NOPART"
else
nopart = P[4] == "NOPART"
end
local def = mcl_potions.registered_effects[P[1]]
if def then
if P[3] == "F" then
local given = mcl_potions.give_effect(P[1], minetest.get_player_by_name(name), tonumber(P[4]), inf and "INF" or tonumber(P[2]), nopart)
if given then
if def.uses_factor then
return true, S("@1 effect given to player @2 for @3 seconds with factor of @4.", def.description, name, P[2], P[4])
else
return true, S("@1 effect given to player @2 for @3 seconds.", def.description, name, P[2])
end
else
return false, S("Giving effect @1 to player @2 failed.", def.description, name)
end
else
local given = mcl_potions.give_effect_by_level(P[1], minetest.get_player_by_name(name), tonumber(P[3]), inf and "INF" or tonumber(P[2]), nopart)
if given then
if def.uses_factor then
return true, S("@1 effect on level @2 given to player @3 for @4 seconds.", def.description, P[3], name, P[2])
else
return true, S("@1 effect given to player @2 for @3 seconds.", def.description, name, P[2])
end
else
return false, S("Giving effect @1 to player @2 failed.", def.description, name)
end
end
else
return false, S("@1 is not an available status effect.", P[1])
end
end,
})

File diff suppressed because it is too large Load Diff

View File

@ -8,14 +8,18 @@ mcl_potions = {}
-- duration effects of glowstone are a time factor of 1/2
-- splash potion duration effects are reduced by a factor of 3/4
mcl_potions.II_FACTOR = 2
mcl_potions.POTENT_FACTOR = 2
mcl_potions.PLUS_FACTOR = 8/3
mcl_potions.INV_FACTOR = 0.50
mcl_potions.DURATION = 180
mcl_potions.DURATION_PLUS = mcl_potions.DURATION * mcl_potions.PLUS_FACTOR
mcl_potions.DURATION_2 = mcl_potions.DURATION / mcl_potions.II_FACTOR
mcl_potions.DURATION_INV = mcl_potions.DURATION * mcl_potions.INV_FACTOR
mcl_potions.DURATION_POISON = 45
mcl_potions.II_FACTOR = mcl_potions.POTENT_FACTOR -- TODO remove at some point
mcl_potions.DURATION_PLUS = mcl_potions.DURATION * mcl_potions.PLUS_FACTOR -- TODO remove at some point
mcl_potions.DURATION_2 = mcl_potions.DURATION / mcl_potions.II_FACTOR -- TODO remove at some point
mcl_potions.INV_FACTOR = 0.50
mcl_potions.SPLASH_FACTOR = 0.75
mcl_potions.LINGERING_FACTOR = 0.25
@ -25,6 +29,7 @@ dofile(modpath .. "/splash.lua")
dofile(modpath .. "/lingering.lua")
dofile(modpath .. "/tipped_arrow.lua")
dofile(modpath .. "/potions.lua")
local potions = mcl_potions.registered_potions
minetest.register_craftitem("mcl_potions:fermented_spider_eye", {
description = S("Fermented Spider Eye"),
@ -332,9 +337,28 @@ minetest.register_craft({
})
local output_table = { }
-- API
-- registers a potion that can be combined with multiple ingredients for different outcomes
-- out_table contains the recipes for those outcomes
function mcl_potions.register_ingredient_potion(input, out_table)
if output_table[input] then
error("Attempt to register the same ingredient twice!")
end
if type(input) ~= "string" then
error("Invalid argument! input must be a string")
end
if type(out_table) ~= "table" then
error("Invalid argument! out_table must be a table")
end
output_table[input] = out_table
end
local water_table = {
["mcl_nether:nether_wart_item"] = "mcl_potions:awkward",
-- ["mcl_potions:fermented_spider_eye"] = "mcl_potions:weakness",
["mcl_potions:fermented_spider_eye"] = "mcl_potions:weakness",
["mcl_potions:speckled_melon"] = "mcl_potions:mundane",
["mcl_core:sugar"] = "mcl_potions:mundane",
["mcl_mobitems:magma_cream"] = "mcl_potions:mundane",
@ -346,134 +370,270 @@ local water_table = {
["mcl_nether:glowstone_dust"] = "mcl_potions:thick",
["mcl_mobitems:gunpowder"] = "mcl_potions:water_splash"
}
-- API
-- register a potion recipe brewed from water
function mcl_potions.register_water_brew(ingr, potion)
if water_table[ingr] then
error("Attempt to register the same ingredient twice!")
end
if type(ingr) ~= "string" then
error("Invalid argument! ingr must be a string")
end
if type(potion) ~= "string" then
error("Invalid argument! potion must be a string")
end
water_table[ingr] = potion
end
mcl_potions.register_ingredient_potion("mcl_potions:river_water", water_table)
mcl_potions.register_ingredient_potion("mcl_potions:water", water_table)
local awkward_table = {
["mcl_potions:speckled_melon"] = "mcl_potions:healing",
["mcl_farming:carrot_item_gold"] = "mcl_potions:night_vision",
["mcl_core:sugar"] = "mcl_potions:swiftness",
["mcl_mobitems:magma_cream"] = "mcl_potions:fire_resistance",
-- ["mcl_mobitems:blaze_powder"] = "mcl_potions:strength",
["mcl_mobitems:blaze_powder"] = "mcl_potions:strength",
["mcl_fishing:pufferfish_raw"] = "mcl_potions:water_breathing",
["mcl_mobitems:ghast_tear"] = "mcl_potions:regeneration",
["mcl_mobitems:spider_eye"] = "mcl_potions:poison",
["mcl_flowers:wither_rose"] = "mcl_potions:withering",
["mcl_mobitems:rabbit_foot"] = "mcl_potions:leaping",
["mcl_flowers:fourleaf_clover"] = "mcl_potions:luck",
["mcl_farming:potato_item_poison"] = "mcl_potions:nausea",
["mcl_mobitems:spectre_membrane"] = "mcl_potions:slow_falling",
["mcl_core:apple_gold"] = "mcl_potions:resistance",
["mcl_mobitems:aery_charge"] = "mcl_potions:haste",
["mcl_mobitems:crystalline_drop"] = "mcl_potions:absorption",
["mcl_mobitems:earthen_ash"] = "mcl_potions:stone_cloak",
["mcl_mobitems:shiny_ice_crystal"] = "mcl_potions:frost",
-- TODO darkness - sculk?
}
-- API
-- register a potion recipe brewed from awkward potion
function mcl_potions.register_awkward_brew(ingr, potion)
if awkward_table[ingr] then
error("Attempt to register the same ingredient twice!")
end
if type(ingr) ~= "string" then
error("Invalid argument! ingr must be a string")
end
if type(potion) ~= "string" then
error("Invalid argument! potion must be a string")
end
awkward_table[ingr] = potion
end
mcl_potions.register_ingredient_potion("mcl_potions:awkward", awkward_table)
local output_table = {
["mcl_potions:river_water"] = water_table,
["mcl_potions:water"] = water_table,
["mcl_potions:awkward"] = awkward_table,
local mundane_table = {
["mcl_potions:fermented_spider_eye"] = "mcl_potions:weakness",
}
local enhancement_table = {}
local extension_table = {}
local potions = {}
for i, potion in ipairs({"healing","harming","swiftness","slowness",
"leaping","poison","regeneration","invisibility","fire_resistance",
-- "weakness","strength",
"water_breathing","night_vision", "withering"}) do
table.insert(potions, potion)
if potion ~= "invisibility" and potion ~= "night_vision" and potion ~= "weakness" and potion ~= "water_breathing" and potion ~= "fire_resistance" then
enhancement_table["mcl_potions:"..potion] = "mcl_potions:"..potion.."_2"
enhancement_table["mcl_potions:"..potion.."_splash"] = "mcl_potions:"..potion.."_2_splash"
table.insert(potions, potion.."_2")
-- API
-- register a potion recipe brewed from mundane potion
function mcl_potions.register_mundane_brew(ingr, potion)
if mundane_table[ingr] then
error("Attempt to register the same ingredient twice!")
end
if potion ~= "healing" and potion ~= "harming" then
extension_table["mcl_potions:"..potion.."_splash"] = "mcl_potions:"..potion.."_plus_splash"
extension_table["mcl_potions:"..potion] = "mcl_potions:"..potion.."_plus"
table.insert(potions, potion.."_plus")
if type(ingr) ~= "string" then
error("Invalid argument! ingr must be a string")
end
if type(potion) ~= "string" then
error("Invalid argument! potion must be a string")
end
for i, potion in ipairs({"awkward", "mundane", "thick", "water"}) do
table.insert(potions, potion)
mundane_table[ingr] = potion
end
mcl_potions.register_ingredient_potion("mcl_potions:mundane", mundane_table)
local thick_table = {
["mcl_crimson:shroomlight"] = "mcl_potions:glowing",
["mcl_mobitems:nether_star"] = "mcl_potions:ominous",
["mcl_mobitems:ink_sac"] = "mcl_potions:blindness",
["mcl_farming:carrot_item_gold"] = "mcl_potions:saturation",
}
-- API
-- register a potion recipe brewed from thick potion
function mcl_potions.register_thick_brew(ingr, potion)
if thick_table[ingr] then
error("Attempt to register the same ingredient twice!")
end
if type(ingr) ~= "string" then
error("Invalid argument! ingr must be a string")
end
if type(potion) ~= "string" then
error("Invalid argument! potion must be a string")
end
thick_table[ingr] = potion
end
mcl_potions.register_ingredient_potion("mcl_potions:thick", thick_table)
local mod_table = { }
-- API
-- registers a brewing recipe altering the potion using a table
-- this is supposed to substitute one item with another
function mcl_potions.register_table_modifier(ingr, modifier)
if mod_table[ingr] then
error("Attempt to register the same ingredient twice!")
end
if type(ingr) ~= "string" then
error("Invalid argument! ingr must be a string")
end
if type(modifier) ~= "table" then
error("Invalid argument! modifier must be a table")
end
mod_table[ingr] = modifier
end
local inversion_table = {
["mcl_potions:healing"] = "mcl_potions:harming",
["mcl_potions:healing_2"] = "mcl_potions:harming_2",
["mcl_potions:swiftness"] = "mcl_potions:slowness",
["mcl_potions:swiftness_plus"] = "mcl_potions:slowness_plus",
["mcl_potions:leaping"] = "mcl_potions:slowness",
["mcl_potions:leaping_plus"] = "mcl_potions:slowness_plus",
["mcl_potions:night_vision"] = "mcl_potions:invisibility",
["mcl_potions:night_vision_plus"] = "mcl_potions:invisibility_plus",
["mcl_potions:poison"] = "mcl_potions:harming",
["mcl_potions:poison_2"] = "mcl_potions:harming_2",
["mcl_potions:healing_splash"] = "mcl_potions:harming_splash",
["mcl_potions:healing_2_splash"] = "mcl_potions:harming_2_splash",
["mcl_potions:swiftness_splash"] = "mcl_potions:slowness_splash",
["mcl_potions:swiftness_plus_splash"] = "mcl_potions:slowness_plus_splash",
["mcl_potions:leaping_splash"] = "mcl_potions:slowness_splash",
["mcl_potions:leaping_plus_splash"] = "mcl_potions:slowness_plus_splash",
["mcl_potions:night_vision_splash"] = "mcl_potions:invisibility_splash",
["mcl_potions:night_vision_plus_splash"] = "mcl_potions:invisibility_plus_splash",
["mcl_potions:poison_splash"] = "mcl_potions:harming_splash",
["mcl_potions:poison_2_splash"] = "mcl_potions:harming_2_splash",
["mcl_potions:luck"] = "mcl_potions:bad_luck",
["mcl_potions:haste"] = "mcl_potions:fatigue",
["mcl_potions:saturation"] = "mcl_potions:food_poisoning",
["mcl_potions:slow_falling"] = "mcl_potions:levitation",
["mcl_potions:absorption"] = "mcl_potions:health_boost",
["mcl_potions:glowing"] = "mcl_potions:darkness", -- TODO remove after adding a direct recipe?
}
-- API
function mcl_potions.register_inversion_recipe(input, output)
if inversion_table[input] then
error("Attempt to register the same input twice!")
end
if type(input) ~= "string" then
error("Invalid argument! input must be a string")
end
if type(output) ~= "string" then
error("Invalid argument! output must be a string")
end
inversion_table[input] = output
end
local function fill_inversion_table() -- autofills with splash and lingering inversion recipes
local filling_table = { }
for input, output in pairs(inversion_table) do
if potions[input].has_splash and potions[output].has_splash then
filling_table[input.."_splash"] = output .. "_splash"
if potions[input].has_lingering and potions[output].has_lingering then
filling_table[input.."_lingering"] = output .. "_lingering"
end
end
end
table.update(inversion_table, filling_table)
mcl_potions.register_table_modifier("mcl_potions:fermented_spider_eye", inversion_table)
end
minetest.register_on_mods_loaded(fill_inversion_table)
local splash_table = {}
local lingering_table = {}
for potion, def in pairs(potions) do
if def.has_splash then
splash_table[potion] = potion.."_splash"
if def.has_lingering then
lingering_table[potion.."_splash"] = potion.."_lingering"
end
end
end
mcl_potions.register_table_modifier("mcl_mobitems:gunpowder", splash_table)
mcl_potions.register_table_modifier("mcl_potions:dragon_breath", lingering_table)
for i, potion in ipairs(potions) do
splash_table["mcl_potions:"..potion] = "mcl_potions:"..potion.."_splash"
lingering_table["mcl_potions:"..potion.."_splash"] = "mcl_potions:"..potion.."_lingering"
local meta_mod_table = { }
-- API
-- registers a brewing recipe altering the potion using a function
-- this is supposed to be a recipe that changes metadata only
function mcl_potions.register_meta_modifier(ingr, mod_func)
if meta_mod_table[ingr] then
error("Attempt to register the same ingredient twice!")
end
if type(ingr) ~= "string" then
error("Invalid argument! ingr must be a string")
end
if type(mod_func) ~= "function" then
error("Invalid argument! mod_func must be a function")
end
meta_mod_table[ingr] = mod_func
end
local function extend_dur(potionstack)
local def = potions[potionstack:get_name()]
if not def then return false end
if not def.has_plus then return false end -- bail out if can't be extended
local potionstack = ItemStack(potionstack)
local meta = potionstack:get_meta()
local potent = meta:get_int("mcl_potions:potion_potent")
local plus = meta:get_int("mcl_potions:potion_plus")
if plus == 0 then
if potent ~= 0 then
meta:set_int("mcl_potions:potion_potent", 0)
end
meta:set_int("mcl_potions:potion_plus", def._default_extend_level)
tt.reload_itemstack_description(potionstack)
return potionstack
end
return false
end
mcl_potions.register_meta_modifier("mesecons:wire_00000000_off", extend_dur)
local mod_table = {
["mesecons:wire_00000000_off"] = extension_table,
["mcl_potions:fermented_spider_eye"] = inversion_table,
["mcl_nether:glowstone_dust"] = enhancement_table,
["mcl_mobitems:gunpowder"] = splash_table,
["mcl_potions:dragon_breath"] = lingering_table,
}
local function enhance_pow(potionstack)
local def = potions[potionstack:get_name()]
if not def then return false end
if not def.has_potent then return false end -- bail out if has no potent variant
local potionstack = ItemStack(potionstack)
local meta = potionstack:get_meta()
local potent = meta:get_int("mcl_potions:potion_potent")
local plus = meta:get_int("mcl_potions:potion_plus")
if potent == 0 then
if plus ~= 0 then
meta:set_int("mcl_potions:potion_plus", 0)
end
meta:set_int("mcl_potions:potion_potent", def._default_potent_level-1)
tt.reload_itemstack_description(potionstack)
return potionstack
end
return false
end
mcl_potions.register_meta_modifier("mcl_nether:glowstone_dust", enhance_pow)
-- Compare two ingredients for compatable alchemy
-- Find an alchemical recipe for given ingredient and potion
-- returns outcome
function mcl_potions.get_alchemy(ingr, pot)
if output_table[pot] then
local brew_selector = output_table[pot:get_name()]
if brew_selector and brew_selector[ingr] then
local meta = pot:get_meta():to_table()
local alchemy = ItemStack(brew_selector[ingr])
local metaref = alchemy:get_meta()
metaref:from_table(meta)
tt.reload_itemstack_description(alchemy)
return alchemy
end
local brew_table = output_table[pot]
if brew_table[ingr] then
return brew_table[ingr]
brew_selector = mod_table[ingr]
if brew_selector then
local brew = brew_selector[pot:get_name()]
if brew then
local meta = pot:get_meta():to_table()
local alchemy = ItemStack(brew)
local metaref = alchemy:get_meta()
metaref:from_table(meta)
tt.reload_itemstack_description(alchemy)
return alchemy
end
end
if mod_table[ingr] then
local brew_table = mod_table[ingr]
if brew_table[pot] then
return brew_table[pot]
end
if meta_mod_table[ingr] then
local brew_func = meta_mod_table[ingr]
if brew_func then return brew_func(pot) end
end
return false
end
mcl_mobs.effect_functions["poison"] = mcl_potions.poison_func
mcl_mobs.effect_functions["regeneration"] = mcl_potions.regeneration_func
mcl_mobs.effect_functions["invisibility"] = mcl_potions.invisiblility_func
mcl_mobs.effect_functions["fire_resistance"] = mcl_potions.fire_resistance_func
mcl_mobs.effect_functions["night_vision"] = mcl_potions.night_vision_func
mcl_mobs.effect_functions["water_breathing"] = mcl_potions.water_breathing_func
mcl_mobs.effect_functions["leaping"] = mcl_potions.leaping_func
mcl_mobs.effect_functions["swiftness"] = mcl_potions.swiftness_func
mcl_mobs.effect_functions["heal"] = mcl_potions.healing_func
mcl_mobs.effect_functions["bad_omen"] = mcl_potions.bad_omen_func
mcl_mobs.effect_functions["withering"] = mcl_potions.withering_func
-- give withering to players in a wither rose
local etime = 0
minetest.register_globalstep(function(dtime)
@ -488,10 +648,6 @@ minetest.register_globalstep(function(dtime)
end)
mcl_wip.register_wip_item("mcl_potions:night_vision")
mcl_wip.register_wip_item("mcl_potions:night_vision_plus")
mcl_wip.register_wip_item("mcl_potions:night_vision_splash")
mcl_wip.register_wip_item("mcl_potions:night_vision_plus_splash")
mcl_wip.register_wip_item("mcl_potions:night_vision_lingering")
mcl_wip.register_wip_item("mcl_potions:night_vision_plus_lingering")
mcl_wip.register_wip_item("mcl_potions:night_vision_arrow")
mcl_wip.register_wip_item("mcl_potions:night_vision_plus_arrow")

View File

@ -11,8 +11,8 @@ end
local lingering_effect_at = {}
local function add_lingering_effect(pos, color, def, is_water, instant)
lingering_effect_at[pos] = {color = color, timer = 30, def = def, is_water = is_water}
local function add_lingering_effect(pos, color, def, is_water, potency, plus)
lingering_effect_at[pos] = {color = color, timer = 30, def = def, is_water = is_water, potency = potency, plus = plus}
end
local function linger_particles(pos, d, texture, color)
@ -55,23 +55,56 @@ minetest.register_globalstep(function(dtime)
end
linger_particles(pos, d, texture, vals.color)
-- Extinguish fire if water bottle
if vals.is_water then
if mcl_potions._extinguish_nearby_fire(pos, d) then
-- -- Extinguish fire if water bottle
-- if vals.is_water then
-- if mcl_potions._extinguish_nearby_fire(pos, d) then
-- vals.timer = vals.timer - 3.25
-- end
-- end
if vals.def.while_lingering and vals.def.while_lingering(pos, d, vals.potency+1) then
vals.timer = vals.timer - 3.25
end
end
-- Affect players and mobs
for _, obj in pairs(minetest.get_objects_inside_radius(pos, d)) do
local entity = obj:get_luaentity()
if obj:is_player() or entity.is_mob then
if obj:is_player() or entity and entity.is_mob then
local applied = false
if vals.def._effect_list then
local ef_level
local dur
for name, details in pairs(vals.def._effect_list) do
if details.uses_level then
ef_level = details.level + details.level_scaling * (vals.potency)
else
ef_level = details.level
end
if details.dur_variable then
dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, vals.plus)
if vals.potency>0 and details.uses_level then
dur = dur / math.pow(mcl_potions.POTENT_FACTOR, vals.potency)
end
dur = dur * mcl_potions.LINGERING_FACTOR
else
dur = details.dur
end
if details.effect_stacks then
ef_level = ef_level + mcl_potions.get_effect_level(obj, name)
end
if mcl_potions.give_effect_by_level(name, obj, ef_level, dur) then
applied = true
end
end
end
vals.def.potion_fun(obj)
-- TODO: Apply timer penalty only if the potion effect was acutally applied
vals.timer = vals.timer - 3.25
if vals.def.custom_effect
and vals.def.custom_effect(obj, (vals.potency+1) * mcl_potions.LINGERING_FACTOR, plus) then
applied = true
end
if applied then vals.timer = vals.timer - 3.25 end
end
end
@ -87,31 +120,44 @@ end)
function mcl_potions.register_lingering(name, descr, color, def)
local id = "mcl_potions:"..name.."_lingering"
local longdesc = def.longdesc
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.")
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 or set of effects, possibly repeatedly.")
if def.longdesc then
longdesc = longdesc .. "\n" .. def.longdesc
longdesc = longdesc .. "\n" .. def._longdesc
end
end
local groups = {brewitem=1, bottle=1, ling_potion=1, _mcl_potion=1}
if def.nocreative then groups.not_in_creative_inventory = 1 end
minetest.register_craftitem(id, {
description = descr,
_tt_help = def.tt,
_tt_help = def._tt,
_dynamic_tt = def._dynamic_tt,
_doc_items_longdesc = longdesc,
_doc_items_usagehelp = S("Use the “Punch” key to throw it."),
stack_max = def.stack_max,
_effect_list = def._effect_list,
uses_level = def.uses_level,
has_potent = def.has_potent,
has_plus = def.has_plus,
_default_potent_level = def._default_potent_level,
_default_extend_level = def._default_extend_level,
inventory_image = lingering_image(color),
groups = {brewitem=1, not_in_creative_inventory=0, bottle=1},
groups = groups,
on_use = function(item, placer, pointed_thing)
local velocity = 10
local dir = placer:get_look_dir();
local pos = placer:getpos();
minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true)
local obj = minetest.add_entity({x=pos.x+dir.x,y=pos.y+2+dir.y,z=pos.z+dir.z}, id.."_flying")
obj:setvelocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity})
obj:setacceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3})
obj:get_luaentity()._thrower = placer:get_player_name()
obj:set_velocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity})
obj:set_acceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3})
local ent = obj:get_luaentity()
ent._thrower = placer:get_player_name()
ent._potency = item:get_meta():get_int("mcl_potions:potion_potent")
ent._plus = item:get_meta():get_int("mcl_potions:potion_plus")
ent._effect_list = def._effect_list
if not minetest.is_creative_enabled(placer:get_player_name()) then
item:take_item()
end
@ -126,6 +172,10 @@ function mcl_potions.register_lingering(name, descr, color, def)
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})
local ent = obj:get_luaentity()
ent._potency = item:get_meta():get_int("mcl_potions:potion_potent")
ent._plus = item:get_meta():get_int("mcl_potions:potion_plus")
ent._effect_list = def._effect_list
end
})
@ -148,7 +198,9 @@ function mcl_potions.register_lingering(name, descr, color, def)
end
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
minetest.sound_play("mcl_potions_breaking_glass", {pos = pos, max_hear_distance = 16, gain = 1})
add_lingering_effect(pos, color, def, name == "water")
local potency = self._potency or 0
local plus = self._plus or 0
add_lingering_effect(pos, color, def, name == "water", potency, plus)
local texture
if name == "water" then
texture = "mcl_particles_droplet_bottle.png"
@ -160,9 +212,7 @@ function mcl_potions.register_lingering(name, descr, color, def)
end
end
linger_particles(pos, d, texture, color)
if name == "water" then
mcl_potions._extinguish_nearby_fire(pos, d)
end
if def.on_splash then def.on_splash(pos, potency+1) end
self.object:remove()
end
end,

View File

@ -1,115 +1,294 @@
# textdomain: mcl_potions
<effect> <duration> [<factor>]=<efekt> <czas trwania> [<czynnik>]
Invisibility=Niewidzialność
body is invisible=ciało jest niewidzialne
Poison=Trucizna
-1 HP / @1 s=-1 PŻ / @1 s
Regeneration=Regeneracja
+1 HP / @1 s=+1 PŻ / @1 s
Strength=Siła
+@1% melee damage=+@1% obrażeń w walce wręcz
Weakness=Osłabienie
-@1% melee damage=-@1% obrażeń w walce wręcz
Water Breathing=Oddychanie pod Wodą
limitless breathing under water=nieograniczone oddychanie pod wodą
Dolphin's Grace=Gracja Delfina
swimming gracefully=pływanie z gracją
Leaping=Zwiększony Skok
+@1% jumping power=+@1% siły skoku
-@1% jumping power=-@1% siły skoku
Slow Falling=Powolne Opadanie
decreases gravity effects=zmniejsza skutki grawitacji
Swiftness=Szybkość
+@1% running speed=+@1% prędkości w biegu
Slowness=Spowolnienie
-@1% running speed=-@1% prędkości w biegu
Levitation=Lewitacja
moves body upwards at @1 nodes/s=porusza ciało w górę z prędkością @1 bloków/s
Night Vision=Noktowizja
improved vision during the night=poprawione widzenie w nocy
Darkness=Ciemność
surrounded by darkness=otoczony ciemnością
not seeing anything beyond @1 nodes=nie widzi nic poza @1 blokami
Glowing=Blask
more visible at all times=bardziej widoczny przez cały czas
Health Boost=Zwiększone Zdrowie
HP increased by @1=PŻ zwiększone o @1
Absorption=Absorpcja
absorbs up to @1 incoming damage=pochłania do @1 otrzymywanych obrażeń
Fire Resistance=Odporność na Ogień
resistance to fire damage=odporność na szkody od ognia
Resistance=Odporność
resist @1% of incoming damage=zmniejsza otrzymywane obrażenia o @1%
Luck=Szczęście
Bad Luck=Pech
Bad Omen=Zły Omen
danger is imminent=zagrożenie jest blisko
Hero of the Village=Bohater Wioski
Withering=Obumieranie
-1 HP / @1 s, can kill=-1 PŻ / @1 s, może zabić
Frost=Mróz
-1 HP / 1 s, can kill, -@1% running speed=-1 PŻ / 1 s, może zabić, -@1% prędkości w biegu
Blindness=Ślepota
impaired sight=upośledzony wzrok
Nausea=Nudności
not feeling very well...=nie czuje się zbyt dobrze
frequency: @1 / 1 s=częstotliwość: @1 / 1 s
Food Poisoning=Zatrucie Pokarmowe
exhausts by @1 per second=wyczerpuje o @1 na sekundę
Saturation=Nasycenie
saturates by @1 per second=nasyca o @1 na sekundę
Haste=Pośpiech
+@1% mining and attack speed=+@1% prędkości kopania i ataku
Fatigue=Zmęczenie
-@1% mining and attack speed=-@1% prędkości kopania i ataku
Conduit Power=Moc Przewodni
+@1% mining and attack speed in water=+@1% prędkości kopania i ataku w wodzie
<effect>|heal|list|clear|remove <duration|heal-amount|effect>|INF [<level>] [<factor>] [NOPART]=<ID-efektu>|heal|list|clear|remove <czas-trwania|ilość-leczenia|ID-efektu>|INF [<poziom>] [<współczynnik>] [NOPART]
Add a status effect to yourself. Arguments: <effect>: name of status effect. Passing "list" as effect name lists available effects. Passing "heal" as effect name heals (or harms) by amount designed by the next parameter. Passing "clear" as effect name removes all effects. Passing "remove" as effect name removes the effect named by the next parameter. <duration>: duration in seconds. Passing "INF" as duration makes the effect infinite. (<heal-amount>: amount of healing when the effect is "heal", passing a negative value subtracts health. <effect>: name of a status effect to be removed when using "remove" as the previous parameter.) <level>: effect power determinant, bigger level results in more powerful effect for effects that depend on the level (no changes for other effects), defaults to 1, pass F to use low-level factor instead. <factor>: effect strength modifier, can mean different things depending on the effect, no changes for effects that do not depend on level/factor. NOPART at the end means no particles will be shown for this effect.=Nadaj efekt statusu dla samego siebie. Argumenty: <ID-efektu>: nazwa efektu statusu (po angielsku). Przekazanie "list" jako nazwa efektu wypisuje dostępne nazwy efektów. Przekazanie "heal" jako nazwa efektu leczy (albo krzywdzi) o ilość określoną następnym parametrem. Przekazanie "clear" jako nazwy efektu usuwa wszystkie efekty. Przekazanie "remove" jako nazwy efektu usuwa efekt określony następnym parametrem. <czas-trwania>: czas trwania w sekundach. Przekazanie "INF" jako czas trwania czyni efekt nieskończonym. (<ilość-leczenia>: ilość leczenia kiedy ID-efektu to "heal", przekazanie liczby ujemnej zabiera zdrowie. <ID-efektu>: nazwa efektu statusu do usunięcia używając "remove" jako poprzedniego parametru.) <poziom>: wyznacznik siły efektu, wyższy poziom skutkuje potężniejszym efektem prze efektach zależnych od poziomu (brak zmiany przy pozostałych), domyślnie 1, przekaż F żeby użyć niskopoziomowego współczynnika zamiast poziomu. <współczynnik>: modyfikator siły efektu, może oznaczać różne rzeczy dla różnych efektów, nie wpływa na efekty, które nie zależą od poziomu/współczynnika. NOPART na końcu oznacza, że cząsteczki nie będą wyświetlane wokół ciebie dla tego efektu.
Missing effect parameter!=Brakujący ID efektu!
Missing or invalid heal amount parameter!=Brakująca lub niewłaściwa ilość leczenia!
Player @1 healed by @2 HP.=Gracz @1 wyleczony o @2 PŻ.
Player @1 harmed by @2 HP.=Gracz @1 skrzywdzony o @2 PŻ.
Effects cleared for player @1=Efekty wyczyszczone dla gracza @1
Removed effect @1 from player @2=Usunięto efekt @1 z gracza @2
@1 is not an available status effect.=@1 nie jest dostępnym efektem.
Missing or invalid duration parameter!=Brakujący lub niewłaściwy czas trwania!
Invalid level parameter!=Niewłaściwy parametr poziomu!
Missing or invalid factor parameter when level is F!=Brakujący lub niewłaściwy współczynnik kiedy poziom to F!
@1 effect given to player @2 for @3 seconds with factor of @4.=Efekt @1 nadany dla gracza @2 na @3 sekund ze współczynnikiem @4.
@1 effect given to player @2 for @3 seconds.=Efekt @1 nadany dla gracza @2 na #3 sekund.
Giving effect @1 to player @2 failed.=Nadawanie efektu @1 dla gracza @2 nie powiodło się.
@1 effect on level @2 given to player @3 for @4 seconds.=Efekt @1 na poziomie @2 nadany dla gracza @3 na @4 sekund.
A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect or a set of status effects.=Mikstura, którą można rzucić, a rozbije się przy uderzeniu, wystawiając wszystkich pobliskich graczy i moby na skutki jej działania.
Use the “Punch” key to throw it.=Użyj przycisku "Uderz" by rzucić.
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 or set of effects, possibly repeatedly.=Mikstura, którą można rzucić, a roztrzaska się przy uderzeniu, tworząc magiczne opary pozostające przez chwilę na ziemi. Jakikolwiek gracz lub mob wewnątrz oparów będzie wystawiony na skutki mikstury, być może wielokrotnie.
This particular arrow is tipped and will give an effect when it hits a player or mob.=Czubek tej strzały jest zanurzony w miksturze, co wystawi jej cel na skutki jej działania.
Use the “Place” key to drink it.=Użyj przycisku "Postaw" by wypić.
Drinking a potion gives you a particular effect or set of effects.=Wypicie mikstury wywoła u ciebie określone skutki.
@1 Potion @2=@1 Mikstura @2
@1 Potion=@1 Mikstura
Potion @1=Mikstura @1
Strange Potion=Dziwna Mikstura
Splash @1=Miotana @1
Lingering @1=Trwała @1
@1 Arrow @2=@1 Strzała @2
@1 Arrow=@1 Strzała
Arrow @1=Strzała @1
Strange Tipped Arrow=Strzała z Dziwnym Grotem
Mighty=Potężna
of Trolling=Trollowania
Dragon's Breath=Oddech Smoka
This item is used in brewing and can be combined with splash potions to create lingering potions.=Ten przedmiot jest używany przy warzeniu i może zostać dodany do miotanych mikstur, aby uczynić je trwałymi.
Awkward=Klarowna
No effect=Brak efektu
Has an awkward taste and is used for brewing potions.=Ma dziwny smak i jest używana do warzenia mikstur.
Mundane=Mdła
Has a terrible taste and is not really useful for brewing potions.=Ma ohydny smak i nie jest zbyt użyteczna przy warzeniu mikstur.
Thick=Gęsta
Has a bitter taste and may be useful for brewing potions.=Ma cierpki smak i może być użyteczna przy warzeniu mikstur.
of Healing=Leczenia
+@1 HP=+@1 PŻ
Instantly heals.=Natychmiast leczy.
of Harming=Krzywdy
-@1 HP=-@1 PŻ
Instantly deals damage.=Natychmiast zadaje obrażenia.
of Night Vision=Noktowizji
Increases the perceived brightness of light under a dark sky.=Zwiększa postrzeganą jasność przy ciemnym niebie.
of Swiftness=Szybkości
Increases walking speed.=Zwiększa prędkość ruchu.
of Slowness=Spowolnienia
Decreases walking speed.=Zmniejsza prędkość ruchu.
of Leaping=Zwiększonego Skoku
Increases jump strength.=Zwiększa siłę skoku.
of Withering=Obumierania
Applies the withering effect which deals damage at a regular interval and can kill.=Zadaje efekt obumierania, zadający obrażenia w regularnych odstępach czasu i mogący zabić.
of Poison=Trucizny
Applies the poison effect which deals damage at a regular interval.=Zadaje efekt trucizny, zadający obrażenia w regularnych odstępach czasu.
of Regeneration=Regeneracji
Regenerates health over time.=Regeneruje życie z upływem czasu.
of Invisibility=Niewidzialności
Grants invisibility.=Daje niewidzialność.
of Water Breathing=Oddychania pod Wodą
Grants limitless breath underwater.=Daje nieograniczony oddech pod wodą.
of Fire Resistance=Odporności na Ogień
Grants immunity to damage from heat sources like fire.=Daje odporność na obrażenia od źródeł ciepła takich jak ogień.
of Strength=Siły
Increases attack power.=Zwiększa siłę ataku.
of Weakness=Osłabienia
Decreases attack power.=Zmniejsza siłę ataku.
of Slow Falling=Powolnego Opadania
Instead of falling, you descend gracefully.=Zamiast spadać, zstępujesz delikatnie.
of Levitation=Lewitacji
Floats body slowly upwards.=Ciało powoli dryfuje w górę.
of Darkness=Ciemności
Surrounds with darkness.=Otacza ciemnością.
of Glowing=Blasku
Highlights for others to see.=Podświetla dla innych do dostrzeżenia.
of Health Boost=Zwiększonego Zdrowia
Increases health.=Zwiększa zdrowie.
of Absorption=Absorpcji
Absorbs some incoming damage.=Pochłania trochę otrzymywanych obrażeń.
of Resistance=Odporności
Decreases damage taken.=Zmniejsza otrzymywane obrażenia.
of Stone Cloak=Kamiennego Płaszcza
Decreases damage taken at the cost of speed.=Zmniejsza otrzymywane obrażenia kosztem prędkości.
of Luck=Szczęścia
Increases luck.=Zwiększa szczęście.
of Bad Luck=Pecha
Decreases luck.=Zmniejsza szczęście.
of Frost=Mrozu
Freezes...=Zamraża...
of Blindness=Ślepoty
Impairs sight.=Upośledza wzrok.
of Nausea=Nudności
Disintegrates senses.=Dezintegruje zmysły.
of Food Poisoning=Zatrucia Pokarmowego
Moves bowels too fast.=Porusza jelitami zbyt szybko.
of Saturation=Nasycenia
Satisfies hunger.=Zaspokaja głód.
of Haste=Pośpiechu
Increases digging and attack speed.=Zwiększa prędkość kopania i ataku.
of Fatigue=Zmęczenia
Decreases digging and attack speed.=Zmniejsza prędkość kopania i ataku.
Ominous=Złowieszcza
Attracts danger.=Przyciąga zagrożenie.
Unknown Potion=Nieznana Mikstura
Right-click to identify=Kliknij prawym przyciskiem myszy, aby zidentyfikować
Unknown Tipped Arrow=Strzała z Nieznanym Grotem
Add a status effect to yourself. Arguments: <effect>: name of status effect, e.g. poison. <duration>: duration in seconds. <factor>: effect strength multiplier (1 @= 100%)=Dodaj status na siebie. Argumenty: <efekt>: nazwa efektu statusu, np. trucizna. <czas trwania>: czas trwania w sekundach. <czynnik>: czynnik siły efektu (1 @= 100%)
Missing effect parameter!=Brak parametru efektu!
Missing or invalid duration parameter!=Brak lub nieprawidłowy parametr czasu trwania!
Invalid factor parameter!=Nieprawidłowy parametr czynnika!
@1 is not an available status effect.=@1 nie jest dostępnym efektem statusu.
Fermented Spider Eye=Fermentowane oko pająka
Try different combinations to create potions.=Wypróbuj różne kombinacje, by stworzyć mikstury.
Glass Bottle=Szklana butelka
Liquid container=Pojemnik na płyn
Liquid container=Zbiornik na ciecz
A glass bottle is used as a container for liquids and can be used to collect water directly.=Szklana butelka jest używana jako pojemnik na płyny i może być wykorzystana bezpośrednio do pozyskiwania wody.
To collect water, use it on a cauldron with water (which removes a level of water) or any water source (which removes no water).=Aby pozyskać wodę użyj jej na kotle z wodą (co usunie jeden poziom wody) lub jakimkolwiek źródle wody (co nie usunie wody).
Water Bottle=Butelka wody
Water bottles can be used to fill cauldrons. Drinking water has no effect.=Butelka wody może być wykorzystana do napełniania kotłów. Picie wody nie ma żadnych efektów.
Water bottles can be used to fill cauldrons. Drinking water has no effect.=Butelka wody może być wykorzystana do napełniania kotłów. Picie wody nie ma żadnych skutków.
Use the “Place” key to drink. Place this item on a cauldron to pour the water into the cauldron.=Użyj przycisku do stawiania aby pić. Postaw ten przedmiot na kotle aby wylać wodę do kotła.
River Water Bottle=Butelka wody rzecznej
River water bottles can be used to fill cauldrons. Drinking it has no effect.=Butelka wody rzecznej może być wykorzystana do napełniania kotłów. Picie jej nie ma żadnego efektu.
River water bottles can be used to fill cauldrons. Drinking it has no effect.=Butelka wody rzecznej może być wykorzystana do napełniania kotłów. Picie jej nie ma żadnego skutku.
Use the “Place” key to drink. Place this item on a cauldron to pour the river water into the cauldron.=Użyj przycisku do stawiania aby pić. Postaw ten przedmiot na kotle aby wylać wodę rzeczną do kotła.
Splash Water Bottle=Miotana butelka wody
Extinguishes fire and hurts some mobs=Gasi ogień i rani niektóre moby
A throwable water bottle that will shatter on impact, where it extinguishes nearby fire and hurts mobs that are vulnerable to water.=Butelka wody którą można rzucać i roztrzaska się przy uderzeniu, gdzie ugasi ogień i rani moby podatne na wodę.
A throwable water bottle that will shatter on impact, where it extinguishes nearby fire and hurts mobs that are vulnerable to water.=Butelka wody, którą można rzucić, a roztrzaska się przy uderzeniu, gdzie ugasi ogień i zrani moby podatne na wodę.
Lingering Water Bottle=Trwała miotana butelka wody
A throwable water bottle that will shatter on impact, where it creates a cloud of water vapor that lingers on the ground for a while. This cloud extinguishes fire and hurts mobs that are vulnerable to water.=Butelka wody którą można rzucać i roztrzaska się przy uderzeniu tworząc opary wody pozostające przez chwilę na ziemi. Opary te gaszą ogień i ranią moby podatne na wodę.
A throwable water bottle that will shatter on impact, where it creates a cloud of water vapor that lingers on the ground for a while. This cloud extinguishes fire and hurts mobs that are vulnerable to water.=Butelka wody którą można rzucić, a roztrzaska się przy uderzeniu, tworząc opary wody pozostające przez chwilę na ziemi. Opary te gaszą ogień i ranią moby podatne na wodę.
Glistering Melon=Błyszczący arbuz
This shiny melon is full of tiny gold nuggets and would be nice in an item frame. It isn't edible and not useful for anything else.=Ten błyszczący arbuz jest pełen tycich odłamków złota i wygląda ładnie w ramkach na przedmioty. Nie jest jadalny ani użyteczny do innych rzeczy.
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.=Mikstura którą można rzucać i roztrzaska się przy uderzeniu tworząc magiczne opary pozostające przez chwilę na ziemi. Jakikolwiek gracz lub mob wewnątrz oparów będzie wystawiony na efekt mikstury.
Use the “Punch” key to throw it.=Użyj przycisku "Uderz" by rzucić.
Use the “Place” key to drink it.=Użyj przycisku "Postaw" by wypić.
Drinking a potion gives you a particular effect.=Wypicie mikstury sprawi, że będziesz wystawiona na jej efekty.
1 HP/@1s | @2=1 HP/@1s | @2
@1 HP=@1 HP
@1 Potion=Mikstura @1
Splash @1 Potion=Miotana mikstura @1
Lingering @1 Potion=Trwała miotana mikstura @1
Arrow of @1=Strzała @1
II= II
IV= IV
@1 Potion@2=Mikstura @1@2
Splash @1@2 Potion=Miotana mikstura @1@2
Lingering @1@2 Potion=Trwała miotana mikstura @1@2
Arrow of @1@2=Strzała @1@2
@1 + Potion=Mikstura @1 +
Splash @1 + Potion=Miotana mikstura @1 +
Lingering @1 + Potion=Trwała miotana mikstura @1 +
Arrow of @1 +=Strzała @1 +
Awkward Potion=Klarowna mikstura
Awkward Splash Potion=Klarowna miotana mikstura
Awkward Lingering Potion=Klarowna trwała miotana mikstura
Has an awkward taste and is used for brewing potions.=Ma dziwny smak i jest użyteczna przy warzenia mikstur.
Mundane Potion=Mdła mikstura
Mundane Splash Potion=Mdła miotana mikstura
Mundane Lingering Potion=Mdła trwała miotana mikstura
Has a terrible taste and is not useful for brewing potions.=Ma ohydny smak i nie jest użyteczna przy warzenia mikstur.
Thick Potion=Gęsta mikstura
Thick Splash Potion=Gęsta miotana mikstura
Thick Lingering Potion=Gęsta trwała miotana mikstura
Has a bitter taste and is not useful for brewing potions.=Ma cierpki smak i nie jest użyteczna przy warzenia mikstur.
Dragon's Breath=Oddech smoka
This item is used in brewing and can be combined with splash potions to create lingering potions.=Ten przedmiot jest używany przy warzeniu i może zostać dodany do miotanych mikstur aby uczynić je trwałymi.
Healing=leczenia
+4 HP=+4 HP
+8 HP=+8 HP
Instantly heals.=Natychmiastowo leczy.
Harming=obrażeń
-6 HP=-6 HP
-12 HP=-12 HP
Instantly deals damage.=Natychmiastowo zadaje obrażenia.
Night Vision=widzenia w ciemności
Increases the perceived brightness of light under a dark sky.=Zwiększa postrzeganą jasność przy ciemnym niebie.
Swiftness=prędkości
Increases walking speed.=Zwiększa prędkość poruszania.
Slowness=spowolnienia
Decreases walking speed.=Zmniejsza prędkość poruszania.
Leaping=skakania
Increases jump strength.=Zwiększa siłę skoku.
Poison=trucizny
Applies the poison effect which deals damage at a regular interval.=Aplikuje efekt trucizny zadający obrażenia w regularnych odstępach czasu.
Regeneration=regeneracji
Regenerates health over time.=Regeneruje życie przez pewien czas.
Invisibility=niewidzialności
Grants invisibility.=Sprawia, że cel jest niewidzialny.
Water Breathing=oddychania pod wodą
Grants limitless breath underwater.=Sprawia, że cel może oddychać pod wodą.
Fire Resistance=odporności na ogień
Grants immunity to damage from heat sources like fire.=Sprawia, że cel jest odporny na obrażenia od źródeł ciepła takich jak ogień.
Weakness=słabości
Weakness +=słabości +
Strength=siły
Strength II=siły II
Strength +=siły +
Try different combinations to create potions.=Spróbuj innej kombinacji aby stworzyć miksturę.
No effect=Brak efektu
A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.=Mikstura, którą można rzucić i rozbije się przy uderzeniu wystawiając wszystkich pobliskich graczy i moby na efekt jej działania.
This particular arrow is tipped and will give an effect when it hits a player or mob.=Czubek tej strzały jest zanurzony w miksturze co wystawi jej cel na efekt jej działania.

View File

@ -1,13 +1,269 @@
# textdomain: mcl_potions
<effect> <duration> [<factor>]=
Invisibility=
body is invisible=
Add a status effect to yourself. Arguments: <effect>: name of status effect, e.g. poison. <duration>: duration in seconds. <factor>: effect strength multiplier (1 @= 100%)=
Poison=
-1 HP / @1 s=
Regeneration=
+1 HP / @1 s=
Strength=
+@1% melee damage=
Weakness=
-@1% melee damage=
Water Breathing=
limitless breathing under water=
Dolphin's Grace=
swimming gracefully=
Leaping=
+@1% jumping power=
-@1% jumping power=
Slow Falling=
decreases gravity effects=
Swiftness=
+@1% running speed=
Slowness=
-@1% running speed=
Levitation=
moves body upwards at @1 nodes/s=
Night Vision=
improved vision during the night=
Darkness=
surrounded by darkness=
not seeing anything beyond @1 nodes=
Glowing=
more visible at all times=
Health Boost=
HP increased by @1=
Absorption=
absorbs up to @1 incoming damage=
Fire Resistance=
resistance to fire damage=
Resistance=
resist @1% of incoming damage=
Luck=
Bad Luck=
Bad Omen=
danger is imminent=
Hero of the Village=
Withering=
-1 HP / @1 s, can kill=
Frost=
-1 HP / 1 s, can kill, -@1% running speed=
Blindness=
impaired sight=
Nausea=
not feeling very well...=
frequency: @1 / 1 s=
Food Poisoning=
exhausts by @1 per second=
Saturation=
saturates by @1 per second=
Haste=
+@1% mining and attack speed=
Fatigue=
-@1% mining and attack speed=
Conduit Power=
+@1% mining and attack speed in water=
<effect>|heal|list|clear|remove <duration|heal-amount|effect>|INF [<level>] [<factor>] [NOPART]=
Add a status effect to yourself. Arguments: <effect>: name of status effect. Passing "list" as effect name lists available effects. Passing "heal" as effect name heals (or harms) by amount designed by the next parameter. Passing "clear" as effect name removes all effects. Passing "remove" as effect name removes the effect named by the next parameter. <duration>: duration in seconds. Passing "INF" as duration makes the effect infinite. (<heal-amount>: amount of healing when the effect is "heal", passing a negative value subtracts health. <effect>: name of a status effect to be removed when using "remove" as the previous parameter.) <level>: effect power determinant, bigger level results in more powerful effect for effects that depend on the level (no changes for other effects), defaults to 1, pass F to use low-level factor instead. <factor>: effect strength modifier, can mean different things depending on the effect, no changes for effects that do not depend on level/factor. NOPART at the end means no particles will be shown for this effect.=
Missing effect parameter!=
Missing or invalid duration parameter!=
Invalid factor parameter!=
Missing or invalid heal amount parameter!=
Player @1 healed by @2 HP.=
Player @1 harmed by @2 HP.=
Effects cleared for player @1=
Removed effect @1 from player @2=
@1 is not an available status effect.=
Missing or invalid duration parameter!=
Invalid level parameter!=
Missing or invalid factor parameter when level is F!=
@1 effect given to player @2 for @3 seconds with factor of @4.=
@1 effect given to player @2 for @3 seconds.=
Giving effect @1 to player @2 failed.=
@1 effect on level @2 given to player @3 for @4 seconds.=
A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect or a set of status effects.=
Use the “Punch” key to throw it.=
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 or set of effects, possibly repeatedly.=
This particular arrow is tipped and will give an effect when it hits a player or mob.=
Use the “Place” key to drink it.=
Drinking a potion gives you a particular effect or set of effects.=
@1 Potion @2=
@1 Potion=
Potion @1=
Strange Potion=
Splash @1=
Lingering @1=
@1 Arrow @2=
@1 Arrow=
Arrow @1=
Strange Tipped Arrow=
Mighty=
of Trolling=
Dragon's Breath=
This item is used in brewing and can be combined with splash potions to create lingering potions.=
Awkward=
No effect=
Has an awkward taste and is used for brewing potions.=
Mundane=
Has a terrible taste and is not really useful for brewing potions.=
Thick=
Has a bitter taste and may be useful for brewing potions.=
of Healing=
+@1 HP=
Instantly heals.=
of Harming=
-@1 HP=
Instantly deals damage.=
of Night Vision=
Increases the perceived brightness of light under a dark sky.=
of Swiftness=
Increases walking speed.=
of Slowness=
Decreases walking speed.=
of Leaping=
Increases jump strength.=
of Withering=
Applies the withering effect which deals damage at a regular interval and can kill.=
of Poison=
Applies the poison effect which deals damage at a regular interval.=
of Regeneration=
Regenerates health over time.=
of Invisibility=
Grants invisibility.=
of Water Breathing=
Grants limitless breath underwater.=
of Fire Resistance=
Grants immunity to damage from heat sources like fire.=
of Strength=
Increases attack power.=
of Weakness=
Decreases attack power.=
of Slow Falling=
Instead of falling, you descend gracefully.=
of Levitation=
Floats body slowly upwards.=
of Darkness=
Surrounds with darkness.=
of Glowing=
Highlights for others to see.=
of Health Boost=
Increases health.=
of Absorption=
Absorbs some incoming damage.=
of Resistance=
Decreases damage taken.=
of Stone Cloak=
Decreases damage taken at the cost of speed.=
of Luck=
Increases luck.=
of Bad Luck=
Decreases luck.=
of Frost=
Freezes...=
of Blindness=
Impairs sight.=
of Nausea=
Disintegrates senses.=
of Food Poisoning=
Moves bowels too fast.=
of Saturation=
Satisfies hunger.=
of Haste=
Increases digging and attack speed.=
of Fatigue=
Decreases digging and attack speed.=
Ominous=
Attracts danger.=
Unknown Potion=
Right-click to identify=
Unknown Tipped Arrow=
Fermented Spider Eye=
Try different combinations to create potions.=
Glass Bottle=
Liquid container=
@ -37,79 +293,3 @@ A throwable water bottle that will shatter on impact, where it creates a cloud o
Glistering Melon=
This shiny melon is full of tiny gold nuggets and would be nice in an item frame. It isn't edible and not useful for anything else.=
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.=
Use the “Punch” key to throw it.=
Use the “Place” key to drink it.=
Drinking a potion gives you a particular effect.=
1 HP/@1s | @2=
@1 HP=
@1 Potion=
Splash @1 Potion=
Lingering @1 Potion=
Arrow of @1=
II=
IV=
@1 Potion@2=
Splash @1@2 Potion=
Lingering @1@2 Potion=
Arrow of @1@2=
@1 + Potion=
Splash @1 + Potion=
Lingering @1 + Potion=
Arrow of @1 +=
Awkward Potion=
Awkward Splash Potion=
Awkward Lingering Potion=
Has an awkward taste and is used for brewing potions.=
Mundane Potion=
Mundane Splash Potion=
Mundane Lingering Potion=
Has a terrible taste and is not useful for brewing potions.=
Thick Potion=
Thick Splash Potion=
Thick Lingering Potion=
Has a bitter taste and is not useful for brewing potions.=
Dragon's Breath=
This item is used in brewing and can be combined with splash potions to create lingering potions.=
Healing=
+4 HP=
+8 HP=
Instantly heals.=
Harming=
-6 HP=
-12 HP=
Instantly deals damage.=
Night Vision=
Increases the perceived brightness of light under a dark sky.=
Swiftness=
Increases walking speed.=
Slowness=
Decreases walking speed.=
Leaping=
Increases jump strength.=
Poison=
Applies the poison effect which deals damage at a regular interval.=
Regeneration=
Regenerates health over time.=
Invisibility=
Grants invisibility.=
Water Breathing=
Grants limitless breath underwater.=
Fire Resistance=
Grants immunity to damage from heat sources like fire.=
Weakness=
Weakness +=
Strength=
Strength II=
Strength +=
Try different combinations to create potions.=
No effect=
A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.=
This particular arrow is tipped and will give an effect when it hits a player or mob.=

File diff suppressed because it is too large Load Diff

View File

@ -13,20 +13,30 @@ end
function mcl_potions.register_splash(name, descr, color, def)
local id = "mcl_potions:"..name.."_splash"
local longdesc = def.longdesc
local longdesc = def._longdesc
if not def.no_effect then
longdesc = S("A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.")
if def.longdesc then
longdesc = longdesc .. "\n" .. def.longdesc
longdesc = S("A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect or a set of status effects.")
if def._longdesc then
longdesc = longdesc .. "\n" .. def._longdesc
end
end
local groups = {brewitem=1, bottle=1, splash_potion=1, _mcl_potion=1}
if def.nocreative then groups.not_in_creative_inventory = 1 end
minetest.register_craftitem(id, {
description = descr,
_tt_help = def.tt,
_tt_help = def._tt,
_dynamic_tt = def._dynamic_tt,
_doc_items_longdesc = longdesc,
_doc_items_usagehelp = S("Use the “Punch” key to throw it."),
stack_max = def.stack_max,
_effect_list = def._effect_list,
uses_level = def.uses_level,
has_potent = def.has_potent,
has_plus = def.has_plus,
_default_potent_level = def._default_potent_level,
_default_extend_level = def._default_extend_level,
inventory_image = splash_image(color),
groups = {brewitem=1, not_in_creative_inventory=0, bottle=1},
groups = groups,
on_use = function(item, placer, pointed_thing)
local velocity = 10
local dir = placer:get_look_dir();
@ -35,7 +45,11 @@ function mcl_potions.register_splash(name, descr, color, def)
local obj = minetest.add_entity({x=pos.x+dir.x,y=pos.y+2+dir.y,z=pos.z+dir.z}, id.."_flying")
obj:set_velocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity})
obj:set_acceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3})
obj:get_luaentity()._thrower = placer:get_player_name()
local ent = obj:get_luaentity()
ent._thrower = placer:get_player_name()
ent._potency = item:get_meta():get_int("mcl_potions:potion_potent")
ent._plus = item:get_meta():get_int("mcl_potions:potion_plus")
ent._effect_list = def._effect_list
if not minetest.is_creative_enabled(placer:get_player_name()) then
item:take_item()
end
@ -50,6 +64,10 @@ function mcl_potions.register_splash(name, descr, color, def)
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})
local ent = obj:get_luaentity()
ent._potency = item:get_meta():get_int("mcl_potions:potion_potent")
ent._plus = item:get_meta():get_int("mcl_potions:potion_plus")
ent._effect_list = def._effect_list
end
})
@ -103,10 +121,10 @@ function mcl_potions.register_splash(name, descr, color, def)
texture = texture.."^[colorize:"..color..":127"
})
if name == "water" then
mcl_potions._extinguish_nearby_fire(pos)
end
self.object:remove()
local potency = self._potency or 0
local plus = self._plus or 0
if def.on_splash then def.on_splash(pos, potency+1) end
for _,obj in pairs(minetest.get_objects_inside_radius(pos, 4)) do
local entity = obj:get_luaentity()
@ -114,14 +132,48 @@ function mcl_potions.register_splash(name, descr, color, def)
local pos2 = obj:get_pos()
local rad = math.floor(math.sqrt((pos2.x-pos.x)^2 + (pos2.y-pos.y)^2 + (pos2.z-pos.z)^2))
if rad > 0 then
def.potion_fun(obj, redux_map[rad])
if def._effect_list then
local ef_level
local dur
for name, details in pairs(def._effect_list) do
if details.uses_level then
ef_level = details.level + details.level_scaling * (potency)
else
def.potion_fun(obj, 1)
ef_level = details.level
end
if details.dur_variable then
dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, plus)
if potency>0 and details.uses_level then
dur = dur / math.pow(mcl_potions.POTENT_FACTOR, potency)
end
dur = dur * mcl_potions.SPLASH_FACTOR
else
dur = details.dur
end
if details.effect_stacks then
ef_level = ef_level + mcl_potions.get_effect_level(obj, name)
end
if rad > 0 then
mcl_potions.give_effect_by_level(name, obj, ef_level, redux_map[rad]*dur)
else
mcl_potions.give_effect_by_level(name, obj, ef_level, dur)
end
end
end
if def.custom_effect then
local power = (potency+1) * mcl_potions.SPLASH_FACTOR
if rad > 0 then
def.custom_effect(obj, redux_map[rad] * power, plus)
else
def.custom_effect(obj, power, plus)
end
end
end
end
self.object:remove()
end
end,
})

View File

@ -37,16 +37,26 @@ local arrow_tt = minetest.registered_items["mcl_bows:arrow"]._tt_help or ""
function mcl_potions.register_arrow(name, desc, color, def)
local longdesc = def.longdesc or ""
local longdesc = def._longdesc or ""
local tt = def._tt or ""
local groups = {ammo=1, ammo_bow=1, brewitem=1, _mcl_potion=1}
if def.nocreative then groups.not_in_creative_inventory = 1 end
minetest.register_craftitem("mcl_potions:"..name.."_arrow", {
description = desc,
_tt_help = arrow_tt .. "\n" .. def.tt,
_tt_help = arrow_tt .. "\n" .. tt,
_dynamic_tt = def._dynamic_tt,
_doc_items_longdesc = arrow_longdesc .. "\n" ..
S("This particular arrow is tipped and will give an effect when it hits a player or mob.") .. "\n" ..
longdesc,
_doc_items_usagehelp = how_to_shoot,
_effect_list = def._effect_list,
uses_level = def.uses_level,
has_potent = def.has_potent,
has_plus = def.has_plus,
_default_potent_level = def._default_potent_level,
_default_extend_level = def._default_extend_level,
inventory_image = "mcl_bows_arrow_inv.png^(mcl_potions_arrow_inv.png^[colorize:"..color..":100)",
groups = { ammo=1, ammo_bow=1, brewitem=1},
groups = groups,
_on_dispense = function(itemstack, dispenserpos, droppos, dropnode, dropdir)
-- Shoot arrow
local shootpos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51))
@ -264,6 +274,9 @@ function mcl_potions.register_arrow(name, desc, color, def)
end
end
local potency = self._potency or 0
local plus = self._plus or 0
-- Punch target object but avoid hurting enderman.
if lua then
if lua.name ~= "mobs_mc:rover" then
@ -271,14 +284,62 @@ function mcl_potions.register_arrow(name, desc, color, def)
full_punch_interval=1.0,
damage_groups={fleshy=self._damage},
}, nil)
def.potion_fun(obj)
if def._effect_list then
local ef_level
local dur
for name, details in pairs(def._effect_list) do
if details.uses_level then
ef_level = details.level + details.level_scaling * (potency)
else
ef_level = details.level
end
if details.dur_variable then
dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, plus)
if potency>0 and details.uses_level then
dur = dur / math.pow(mcl_potions.POTENT_FACTOR, potency)
end
else
dur = details.dur
end
dur = dur * mcl_potions.SPLASH_FACTOR
if details.effect_stacks then
ef_level = ef_level + mcl_potions.get_effect_level(obj, name)
end
mcl_potions.give_effect_by_level(name, obj, ef_level, dur)
end
end
if def.custom_effect then def.custom_effect(obj, potency+1, plus) end
end
else
obj:punch(self.object, 1.0, {
full_punch_interval=1.0,
damage_groups={fleshy=self._damage},
}, nil)
def.potion_fun(obj)
if def._effect_list then
local ef_level
local dur
for name, details in pairs(def._effect_list) do
if details.uses_level then
ef_level = details.level + details.level_scaling * (potency)
else
ef_level = details.level
end
if details.dur_variable then
dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, plus)
if potency>0 and details.uses_level then
dur = dur / math.pow(mcl_potions.POTENT_FACTOR, potency)
end
else
dur = details.dur
end
dur = dur * mcl_potions.SPLASH_FACTOR
if details.effect_stacks then
ef_level = ef_level + mcl_potions.get_effect_level(obj, name)
end
mcl_potions.give_effect_by_level(name, obj, ef_level, dur)
end
end
if def.custom_effect then def.custom_effect(obj, potency+1, plus) end
end
if is_player then

View File

@ -7,41 +7,63 @@ local eat = minetest.item_eat(6, "mcl_core:bowl") --6 hunger points, player rece
local flower_effect = {
[ "mcl_flowers:allium" ] = "fire_resistance",
[ "mcl_flowers:azure_bluet" ] = "blindness",
[ "mcl_flowers:lily_of_the_valley" ] = "poison",
[ "mcl_flowers:blue_orchid" ] = "hunger",
[ "mcl_flowers:dandelion" ] = "hunger",
[ "mcl_flowers:blue_orchid" ] = "saturation",
[ "mcl_flowers:dandelion" ] = "saturation",
[ "mcl_flowers:cornflower" ] = "jump",
[ "mcl_flowers:oxeye_daisy" ] = "regeneration",
[ "mcl_flowers:poppy" ] = "night_vision"
[ "mcl_flowers:poppy" ] = "night_vision",
[ "mcl_flowers:wither_rose" ] = "withering",
[ "mcl_flowers:tulip_orange" ] = "weakness",
[ "mcl_flowers:tulip_pink" ] = "weakness",
[ "mcl_flowers:tulip_red" ] = "weakness",
[ "mcl_flowers:tulip_white" ] = "weakness",
}
local effects = {
[ "fire_resistance" ] = function(itemstack, placer, pointed_thing)
mcl_potions.fire_resistance_func(placer, 1, 4)
return eat(itemstack, placer, pointed_thing)
end,
[ "poison" ] = function(itemstack, placer, pointed_thing)
mcl_potions.poison_func(placer, 1, 12)
mcl_potions.give_effect("fire_resistance", placer, 1, 4)
return eat(itemstack, placer, pointed_thing)
end,
[ "hunger" ] = function(itemstack, placer, pointed_thing, player)
mcl_hunger.item_eat(6, "mcl_core:bowl", 3.5, 0, 100)
[ "blindness" ] = function(itemstack, placer, pointed_thing)
mcl_potions.give_effect("blindness", placer, 1, 8)
return eat(itemstack, placer, pointed_thing)
end,
[ "poison" ] = function(itemstack, placer, pointed_thing)
mcl_potions.give_effect_by_level("poison", placer, 1, 12)
return eat(itemstack, placer, pointed_thing)
end,
[ "saturation" ] = function(itemstack, placer, pointed_thing, player)
mcl_potions.give_effect_by_level("saturation", placer, 1, 0.5)
return eat(itemstack, placer, pointed_thing)
end,
["jump"] = function(itemstack, placer, pointed_thing)
mcl_potions.leaping_func(placer, 1, 6)
mcl_potions.give_effect_by_level("leaping", placer, 1, 6)
return eat(itemstack, placer, pointed_thing)
end,
["regeneration"] = function(itemstack, placer, pointed_thing)
mcl_potions.regeneration_func(placer, 1, 8)
mcl_potions.give_effect_by_level("regeneration", placer, 1, 8)
return eat(itemstack, placer, pointed_thing)
end,
["withering"] = function(itemstack, placer, pointed_thing)
mcl_potions.give_effect_by_level("withering", placer, 1, 8)
return eat(itemstack, placer, pointed_thing)
end,
["weakness"] = function(itemstack, placer, pointed_thing)
mcl_potions.give_effect_by_level("weakness", placer, 1, 9)
return eat(itemstack, placer, pointed_thing)
end,
["night_vision"] = function(itemstack, placer, pointed_thing)
mcl_potions.night_vision_func(placer, 1, 5)
mcl_potions.give_effect("night_vision", placer, 1, 5)
return eat(itemstack, placer, pointed_thing)
end,
}

View File

@ -23,7 +23,32 @@ mcl_damage.register_modifier(function(obj, damage, reason)
texture = "mcl_particles_crit.png^[colorize:#bc7a57:127",
})
minetest.sound_play("mcl_criticals_hit", {object = obj})
return damage * math.random(1.5, 2.5)
local crit_mod
local CRIT_MIN = 1.5
local CRIT_DIFF = 1
if hitter:is_player() then
local luck = mcl_luck.get_luck(hitter:get_player_name())
if luck ~= 0 then
local a, d
if luck > 0 then
d = -0.5
a = d - math.abs(luck)
elseif luck < 0 then
a = -0.5
d = a - math.abs(luck)
else
minetest.log("warning", "[mcl_criticals] luck is not a number") -- this technically can't happen, but want to catch such cases
end
if a then
local x = math.random()
crit_mod = CRIT_DIFF * (a * x) / (d - luck * x) + CRIT_MIN
end
end
end
if not crit_mod then
crit_mod = math.random(CRIT_MIN, CRIT_MIN + CRIT_DIFF)
end
return damage * crit_mod
end
end
end, -100)

View File

@ -1,2 +1,2 @@
name = mcl_criticals
depends = mcl_damage
depends = mcl_damage, mcl_luck

View File

@ -75,7 +75,7 @@ minetest.register_on_respawnplayer(function(player)
mcl_fovapi.remove_all_modifiers(player)
end)
function mcl_fovapi.apply_modifier(player, modifier_name)
function mcl_fovapi.apply_modifier(player, modifier_name, time_override)
if not player or not modifier_name then
return
end
@ -106,13 +106,14 @@ function mcl_fovapi.apply_modifier(player, modifier_name)
minetest.log("FOV::Modifier applied to player:" .. player_name .. " modifier: " .. modifier_name)
end
local time = time_override or modifier.time
-- modifier apply code.
if modifier.exclusive == true then
-- if exclusive, reset the player's fov, and apply the new fov.
if modifier.is_multiplier then
player:set_fov(0, false, 0)
end
player:set_fov(modifier.fov_factor, modifier.is_multiplier, modifier.time)
player:set_fov(modifier.fov_factor, modifier.is_multiplier, time)
else
-- not exclusive? let's apply it in the mix.
local fov_factor, is_mult = player:get_fov()
@ -126,15 +127,15 @@ function mcl_fovapi.apply_modifier(player, modifier_name)
fov_factor = (fov_factor + modifier.fov_factor) / 2
end
if modifier.is_multiplier and is_mult then
player:set_fov(fov_factor, true, modifier.time)
player:set_fov(fov_factor, true, time)
else
player:set_fov(fov_factor, false, modifier.time)
player:set_fov(fov_factor, false, time)
end
end
end
function mcl_fovapi.remove_modifier(player, modifier_name)
function mcl_fovapi.remove_modifier(player, modifier_name, time_override)
if not player or not modifier_name then
return
end
@ -159,9 +160,10 @@ function mcl_fovapi.remove_modifier(player, modifier_name)
applied[k] = mcl_fovapi.registered_modifiers[k]
end
local time = time_override or modifier.reset_time
local elem = next
if elem(applied) == nil then
player:set_fov(0, false, modifier.reset_time)
player:set_fov(0, false, time)
return
end
local exc = false
@ -191,7 +193,7 @@ function mcl_fovapi.remove_modifier(player, modifier_name)
fov_factor = fov_factor * x.fov_factor
end
end
player:set_fov(fov_factor, not non_multiplier_added, modifier.reset_time)
player:set_fov(fov_factor, not non_multiplier_added, time)
end
if mcl_fovapi.registered_modifiers[modifier_name].on_end then

View File

@ -99,42 +99,6 @@ function mcl_hunger.reset_bars_poison_hunger(player)
end
end
-- Poison player
local function poisonp(tick, time, time_left, damage, exhaustion, name)
if not mcl_hunger.active then
return
end
local player = minetest.get_player_by_name(name)
-- First check if player is still there
if not player then
return
end
-- Abort if food poisonings have been stopped
if mcl_hunger.poison_hunger[name] == 0 then
return
end
time_left = time_left + tick
if time_left < time then
minetest.after(tick, poisonp, tick, time, time_left, damage, exhaustion, name)
else
if exhaustion > 0 then
mcl_hunger.poison_hunger [name] = mcl_hunger.poison_hunger[name] - 1
end
if mcl_hunger.poison_hunger[name] <= 0 then
mcl_hunger.reset_bars_poison_hunger(player)
end
end
-- Deal damage and exhaust player
-- TODO: Introduce fatal poison at higher difficulties
if player:get_hp()-damage > 0 then
mcl_util.deal_damage(player, damage, {type = "hunger"})
end
mcl_hunger.exhaust(name, exhaustion)
end
local poisonrandomizer = PseudoRandom(os.time())
function mcl_hunger.item_eat(hunger_change, replace_with_item, poisontime, poison, exhaust, poisonchance, sound)
@ -186,15 +150,8 @@ function mcl_hunger.item_eat(hunger_change, replace_with_item, poisontime, poiso
do_poison = true
end
if do_poison then
-- Set food poison bars
if exhaust and exhaust > 0 then
hb.change_hudbar(user, "hunger", nil, nil, "mcl_hunger_icon_foodpoison.png", nil, "mcl_hunger_bar_foodpoison.png")
if mcl_hunger.debug then
hb.change_hudbar(user, "exhaustion", nil, nil, nil, nil, "mcl_hunger_bar_foodpoison.png")
end
mcl_hunger.poison_hunger[name] = mcl_hunger.poison_hunger[name] + 1
end
poisonp(1, poisontime, 0, poison, exhaust, user:get_player_name())
local level = mcl_potions.get_effect_level(user, "food_poisoning")
mcl_potions.give_effect_by_level("food_poisoning", user, level+exhaust, poisontime)
end
end

View File

@ -247,13 +247,13 @@ minetest.register_globalstep(function(dtime)
food_tick_timer = 0
-- let hunger work always
if player_health > 0 and player_health <= 20 then
if player_health > 0 then
--mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_HUNGER) -- later for hunger status effect
mcl_hunger.update_exhaustion_hud(player)
end
if food_level >= 18 then -- slow regeneration
if player_health > 0 and player_health < 20 then
if player_health > 0 and player_health < player:get_properties().hp_max then
player:set_hp(player_health+1)
mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN)
mcl_hunger.update_exhaustion_hud(player)
@ -270,7 +270,7 @@ minetest.register_globalstep(function(dtime)
end
elseif food_tick_timer > max_tick_timer and food_level == 20 and food_saturation_level > 0 then -- fast regeneration
if player_health > 0 and player_health < 20 then
if player_health > 0 and player_health < player:get_properties().hp_max then
food_tick_timer = 0
player:set_hp(player_health+1)
mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN)

View File

@ -1,7 +1,7 @@
-- Apply food poisoning effect as long there are no real status effect.
-- TODO: Remove this when food poisoning a status effect in mcl_potions.
-- TODO: Sanitize this now that Food Poisoning is now an effect in mcl_potions
-- Normal poison damage is set to 0 because it's handled elsewhere.
mcl_hunger.register_food("mcl_mobitems:rotten_flesh", 4, "", 30, 0, 100, 80)
mcl_hunger.register_food("mcl_mobitems:chicken", 2, "", 30, 0, 100, 30)
mcl_hunger.register_food("mcl_fishing:pufferfish_raw", 1, "", 15, 0, 300)
mcl_hunger.register_food("mcl_mobitems:rotten_flesh", 4, "", 30, 0, 1, 80)
mcl_hunger.register_food("mcl_mobitems:chicken", 2, "", 30, 0, 1, 30)
mcl_hunger.register_food("mcl_fishing:pufferfish_raw", 1, "", 15, 0, 3)

View File

@ -0,0 +1,33 @@
mcl_luck = {}
-- table indexed by player name
-- each entry for each player contains list of modifiers applied to the player
-- modifiers are listed by their name (defined when applying them)
-- all modifiers are dynamic (they are removed when the player leaves game and on server shutdown)
local applied_luck = {}
function mcl_luck.apply_luck_modifier(player_name, modifier_name, amount)
applied_luck[player_name][modifier_name] = amount
end
function mcl_luck.remove_luck_modifier(player_name, modifier_name)
applied_luck[player_name][modifier_name] = nil
end
function mcl_luck.get_luck(player_name)
local luck = 0
for _, amount in pairs(applied_luck[player_name]) do
luck = luck + amount
end
return luck
end
minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
applied_luck[player_name] = {}
end)
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
applied_luck[player_name] = nil
end)

View File

@ -0,0 +1,3 @@
name = mcl_luck
author = Herowl
description = An API for handling luck, it can be polled by random events.

View File

@ -76,13 +76,16 @@ else
end
function mcl_meshhand.update_player(player)
local hand
if mcl_skins_enabled then
local node_id = mcl_skins.get_node_id_by_player(player)
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:" .. node_id)
hand = ItemStack("mcl_meshhand:" .. node_id)
else
local creative = minetest.is_creative_enabled(player:get_player_name())
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:hand" .. (creative and "_crea" or "_surv"))
hand = ItemStack("mcl_meshhand:hand" .. (creative and "_crea" or "_surv"))
end
if not mcl_potions then player:get_inventory():set_stack("hand", 1, hand) end
player:get_inventory():set_stack("hand", 1, mcl_potions.hf_update_internal(hand, player))
end
minetest.register_on_joinplayer(function(player)

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Some files were not shown because too many files have changed in this diff Show More