Compare commits

..

91 Commits

Author SHA1 Message Date
the-real-herowl 576f887e07 Added a darkness potion recipe 2024-05-02 04:17:16 +02:00
the-real-herowl 6cd83e1bda Updated Polish translation 2024-05-02 04:14:55 +02:00
the-real-herowl 3cbeb84f49 Added a few mobitems
* one droppable from strays
* the rest will get their mobs in a later update
* added alternative ways to get the items
* added recipes for potions that use these items
2024-05-02 04:09:39 +02:00
the-real-herowl 44bd058060 Updated Polish translation 2024-05-02 02:57:18 +02:00
the-real-herowl b57b42fd61 Update template.txt 2024-05-02 02:57:18 +02:00
the-real-herowl 588db6b0dc Improved compat alias visual 2024-05-02 02:57:18 +02:00
the-real-herowl 77857397a3 Fix a crash 2024-05-02 02:57:18 +02:00
the-real-herowl 764aa14f21 Fixed mob drops not having proper description 2024-05-02 02:57:18 +02:00
the-real-herowl 8f07f70da4 Legacy potion conversion extended 2024-05-02 02:57:18 +02:00
the-real-herowl 15d75fb73e Legacy potions converter 2024-05-02 02:57:18 +02:00
the-real-herowl 057ae6fceb Guardian fixes 2024-05-02 02:57:18 +02:00
the-real-herowl ec97707412 Add more sus stew effects 2024-05-02 02:57:18 +02:00
the-real-herowl 31d0631b7d Migrated mobs to the new effects API 2024-05-02 02:57:18 +02:00
the-real-herowl ef920c1cde Migrated beacons to the new API
Also added more effects to them
2024-05-02 02:57:18 +02:00
the-real-herowl 188ff88e07 Strays now use frost arrows 2024-05-02 02:57:18 +02:00
the-real-herowl a331925f9d Move most of the game to the new API 2024-05-02 02:57:18 +02:00
the-real-herowl 10de2aed63 Documentation update 2024-05-02 02:57:18 +02:00
the-real-herowl dee4a14167 Support delayed drinking with new potions API 2024-05-02 02:57:18 +02:00
the-real-herowl d6cbbdb861 Added effect stacking option to the potions API
Also:
* Frost and Food Poisoning potion now stack their effects
* fixed a crash related to tipped arrows
2024-05-02 02:57:18 +02:00
the-real-herowl c839ba4144 Plant placement and drop fixes 2024-05-02 02:57:07 +02:00
the-real-herowl 8fcb48fbf3 Added on_save_effect support for mobs 2024-05-02 02:55:41 +02:00
the-real-herowl 28b3d479ba Fixed effects still being handled after mob death 2024-05-02 02:55:41 +02:00
the-real-herowl f2116a1a05 Effects persist on loads for mobs too 2024-05-02 02:55:41 +02:00
the-real-herowl 1bcbf72cf0 Remove unused function in mcl_hunger 2024-05-02 02:55:40 +02:00
the-real-herowl 0ffa195f93 Added some potion recipes
Also:
* changed the duration of saturation and food poisoning potions
* minor code changes
2024-05-02 02:55:40 +02:00
the-real-herowl cb00027944 Added the ominous potion 2024-05-02 02:55:40 +02:00
the-real-herowl 76c05e5a1e Improved API mob support
* various API functions now work with mobs properly
* the following effects don't work with mobs at all:
  water breathing, dolphin's grace, leaping, swiftness,
  slowness, slow falling, night vision, darkness, frost,
  health boost, absorption, fire resistance, resistance,
  luck, bad luck, blindness, nausea, hunger, saturation,
  haste, fatigue, conduit power
* the following effects should work with mobs:
  invisibility, regeneration, poison, withering,
  strength, weakness, levitation, glowing
* the following effects have no effect on mobs
  (but can be applied with the API):
  bad omen, hero of the village
2024-05-02 02:55:40 +02:00
the-real-herowl 858d7f6c16 Allowed infinite effect duration 2024-05-02 02:55:40 +02:00
the-real-herowl 1349945fdc Added the option to remove and clear effects...
...with the /effect command.
Also made the API for clearing effects more robust.
2024-05-02 02:55:40 +02:00
the-real-herowl 11b3cfe68a Allowed giving effect without particles
...both with API and the /effect command
2024-05-02 02:55:40 +02:00
the-real-herowl e42d423113 Typos fixed 2024-05-02 02:55:40 +02:00
the-real-herowl f5fe19960e Tooltip and color fixes 2024-05-02 02:55:40 +02:00
the-real-herowl 16ebc17090 Expanded brewing recipe API
Added recipes using thick or mundane potion
2024-05-02 02:55:40 +02:00
the-real-herowl 6d7cabbad9 Added potions for new effects
* also added some new brewing recipes
2024-05-02 02:55:40 +02:00
the-real-herowl df8cca6148 Added strength and weakness potions
Also fixed potent slowness potion level
Also fixed slowness and swiftness effect descriptions
2024-05-02 02:55:40 +02:00
the-real-herowl 6768bf06c6 New brewing recipes registering API
Also migrated all recipes to the new system
2024-05-02 02:55:40 +02:00
the-real-herowl 0ee99277f1 Brewing fully works with the new system 2024-05-02 02:55:40 +02:00
the-real-herowl 0f1a2d4910 Brewing somewhat works with the new API 2024-05-02 02:55:40 +02:00
the-real-herowl 6848944d5e Added glowing effect
Also added on_save_effect callback to run cleanup
2024-05-02 02:55:40 +02:00
the-real-herowl a0ff75e995 Fixed running on_end for effects that aren't ending 2024-05-02 02:55:40 +02:00
the-real-herowl c7348e6697 Reserve some more keywords in register_effect() 2024-05-02 02:55:40 +02:00
the-real-herowl fd96a52631 Further (mcl_)luck functionality
* XP from mob breeding impacted by luck
* eye of ender explosion chance impacted by luck
* fishing loot impacted by luck
* melee critical damage impacted by luck
* also fixed 2 scripts marked as "executable"
2024-05-02 02:55:40 +02:00
the-real-herowl a9f255a893 Made some random rolls affected by mcl_luck
* xp bottle
* bow and crossbow crits
* megacrits added for mcl_bows, achievable only by (mcl_)luck
2024-05-02 02:55:40 +02:00
the-real-herowl 2d7a1e34be Added mcl_luck API
Luck and Bad Luck effects use the mcl_luck API now
The API is unused for now
2024-05-02 02:55:40 +02:00
the-real-herowl 157c03e4ab Added luck and bad luck effects
They're no-op for now
2024-05-02 02:55:40 +02:00
the-real-herowl 8ebe983877 Added some effect descriptions 2024-05-02 02:55:40 +02:00
the-real-herowl a64d6ba62b Added conduit power 2024-05-02 02:55:40 +02:00
the-real-herowl 140affe36e Haste and fatigue expanded and improved
* abstracted and refactored some parts of haste and fatigue
* added and exposed new mcl_potions API functions
* fixed haste and fatigue not altering the hand
* mcl_meshhand now calls into mcl_potions when resetting the hand
2024-05-02 02:55:40 +02:00
the-real-herowl 5c2ed0b0a9 Capped fatigue effect on punching
This fixes a crash, too
Also updates toolcaps on gamemode change
2024-05-02 02:55:40 +02:00
the-real-herowl 3e308da1e5 Improved haste and fatigue effects
* fixed a few crashes related to unusual effect levels
* added haste and fatigue combat functionality
* added some cleanup to avoid hangover unstackable items
* capped the slowdown from fatigue at 5 minutes digging time
* (despite the above, if a tool has a longer time set in definition,
	that still works)
* removed an unused "global" variable
2024-05-02 02:55:40 +02:00
the-real-herowl 3ac9bbcb49 Added haste and fatigue 2024-05-02 02:55:40 +02:00
the-real-herowl b00c5076cf Added dolphin's grace 2024-05-02 02:55:40 +02:00
the-real-herowl 4c47d78d58 Added strength and weakness effects
* also highest effect level displayed in HUD set to 3000
* also improved indicating effects with strange factors in HUD
2024-05-02 02:55:40 +02:00
the-real-herowl 6730b613c1 Renamed some functions and variables
* changed names referring to player where it does support mobs
* also added an is_player() check in one function
2024-05-02 02:55:40 +02:00
the-real-herowl aab5619c3c Improved descriptions 2024-05-02 02:55:40 +02:00
the-real-herowl deed51bf5c Improved nausea 2024-05-02 02:55:40 +02:00
the-real-herowl 30173829fd Added time_override to FOV API
time_override can be used when applying or removing modifiers
2024-05-02 02:55:40 +02:00
the-real-herowl 312321a67b Improved the darkness effect 2024-05-02 02:55:40 +02:00
the-real-herowl c1ec962873 Added darkness 2024-05-02 02:55:40 +02:00
the-real-herowl ef3625623d Added nausea 2024-05-02 02:55:40 +02:00
the-real-herowl 1ae1cb8aed Fixed graphical features of some effects
* loading fixed (by adding on_load)
* absorption bar never reaching end fixed
2024-05-02 02:55:40 +02:00
the-real-herowl d012e00a7b Added blindness effect
(also improved TT descriptions of some effects)
2024-05-02 02:55:40 +02:00
the-real-herowl 584eccbb1f Added frost effect 2024-05-02 02:55:40 +02:00
the-real-herowl e04ced0809 Added HP hudbar look modifier API
(for now in mcl_potions)
2024-05-02 02:55:40 +02:00
the-real-herowl 26e7f14065 Add hero of the village effect 2024-05-02 02:55:40 +02:00
the-real-herowl b29f29f48a Added food poisoning and saturation effects 2024-05-02 02:55:40 +02:00
the-real-herowl 19d8c86eba Added some missing effects and improved API
* added a way to have a damage modifier relying on type instead of flag
* added Slow Falling
* added Levitation
* added Health Boost
* added Absorption
2024-05-02 02:55:40 +02:00
the-real-herowl f4d404b881 Improved damage mods in effects, resistance effect 2024-05-02 02:55:40 +02:00
the-real-herowl f821b4d704 New effect icons 2024-05-02 02:55:40 +02:00
the-real-herowl e7be186e76 Improved effects HUD and fixes
* Fixed some effects not being replaced correctly with higher levels
* Implemented an old FIXME (MTE 5.3.0 fixed underlying bug)
* Added a way to obtain an approximate level of effect from factor
* Added effect level to HUD under the icon
* Added effect timer to HUD under the icon
2024-05-02 02:55:40 +02:00
the-real-herowl 3aa6a2a816 Improved /effect command return messages
Also improved the name of a variable
2024-05-02 02:55:40 +02:00
the-real-herowl b6a574ae66 Registered dragon breath and pruned code
* removed old registration code
* added to the API the `nocreative` field
* registered the bottled dragon's breath as an item
2024-05-02 02:55:39 +02:00
the-real-herowl b2fa904cc3 Re-registered potions under new API 2024-05-02 02:55:39 +02:00
the-real-herowl bcab17bb79 Added a constant to the API 2024-05-02 02:55:39 +02:00
the-real-herowl 98ac9dbe4c Fixed tipped arrow descriptions 2024-05-02 02:55:39 +02:00
the-real-herowl 2f0770120d Added missing effect descriptions 2024-05-02 02:55:39 +02:00
the-real-herowl 0bb7f3c4ea Fixed splash and lingering potions
* descriptions
* scaling
2024-05-02 02:55:39 +02:00
the-real-herowl 5f4e40afc0 Added support for varied descriptions 2024-05-02 02:55:39 +02:00
the-real-herowl 8aaf6071c4 Implemented missing potion registering functionality
* improved support for custom (non-status) effects
* added support for splash potions
* added support for lingering potions
* added support for tipped arrows
* removed the old registration
2024-05-02 02:55:39 +02:00
the-real-herowl 72af54c373 Improved potion descriptions
* added support for effect descriptions
* added descriptions for some effects
* fixed a crash
2024-05-02 02:55:39 +02:00
the-real-herowl 515796e035 Potions registering API fully works with creative 2024-05-02 02:55:39 +02:00
the-real-herowl 837d5e11d2 Fixed variable definitions ("undeclared global") 2024-05-02 02:55:39 +02:00
the-real-herowl 8f6f7123d1 Creative inventory using new potions API
-creative inventory utilizes the new potions API
-the new fancy tooltips are used there
2024-05-02 02:55:39 +02:00
the-real-herowl 59fe5e9ec1 Added new potion tooltip handling
-potion tooltips are now utilizing the power of the new API
-potion names change based on metadata
-nothing triggers loading the new tooltips beyond the names for now
2024-05-02 02:55:39 +02:00
the-real-herowl e1fed9877a Added new potions registering API
-added comprehensive potions registering API
-new API registers only drinkable potions for now
-new API is compatible with very complex tooltips
-new API can have multiple effects per potion
-no hardcoding for specific potions in the new API
2024-05-02 02:55:39 +02:00
the-real-herowl 7632054478 Translatable effect names and cleanup
-added translatable effect names to the API
-made /effect utilize those descriptions
-cleaned up variables/constants to go with further API changes
2024-05-02 02:55:39 +02:00
the-real-herowl 0a9b021fbe Arabic-to-Roman converter redo
-rewrote the Arabic-to-Roman number converter
-moved it to mcl_util
2024-05-02 02:55:39 +02:00
the-real-herowl e429c5f755 Reimplemented /effect heal and fixed bugs
-heal subcommand to the /effect reimplemented
-healing_func() from old API standardized, included in new API
-(the last point is due to it being substantially different from others)
-fixed a few bugs, potential crashes
-fixed incorrect withering effect progression
-standardized variable naming
2024-05-02 02:55:39 +02:00
the-real-herowl 8b1d36c6e1 Resolved merge conflict 2024-05-02 02:55:39 +02:00
the-real-herowl d10f0a6efb Improved /effect command and fixes
-improved the /effect command, allowing to use effect levels
-fixed a bug in level-to-factor conversions
-renamed effect icons to follow the new convention
2024-05-02 02:55:39 +02:00
the-real-herowl dd70622276 General effects API overhaul
- added a `register_effect()` function
- added the withering effect
- registered all the old effects under the new API
- unified effect names
- updated the main effect checker to use the new API
- changed some hardcoded values to support the unified effect naming
- added new namespaced metadata effects strings
- added support for legacy effect player metadata
- potions are still using the old effects API
- added glue between old API calls and the new API
- renamed the effect icons to support the unified effect naming
2024-05-02 02:55:39 +02:00
165 changed files with 4336 additions and 2476 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

@ -6,6 +6,9 @@ local pool = {}
local tick = false
minetest.register_on_joinplayer(function(player)
pool[player:get_player_name()] = 0
end)
@ -127,6 +130,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)
@ -169,17 +173,17 @@ minetest.register_globalstep(function(_)
local pos = player:get_pos()
if tick == true and (pool[name] or 0) > 0 then
if tick == true and pool[name] > 0 then
minetest.sound_play("item_drop_pickup", {
pos = pos,
gain = 0.3,
max_hear_distance = 16,
pitch = math.random(70, 110) / 100
})
if (pool[name] or 0) > 6 then
if pool[name] > 6 then
pool[name] = 6
else
pool[name] = (pool[name] or 1) - 1
pool[name] = pool[name] - 1
end
end

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
@ -1142,9 +1149,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

@ -324,6 +324,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
@ -374,7 +375,7 @@ function mcl_mobs.register_arrow(name, def)
rotate = def.rotate,
on_punch = def.on_punch or function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
local vel = self.object:get_velocity():length()
self.object:set_velocity(dir * vel)
self.object:set_velocity({x=dir.x * vel, y=dir.y * vel, z=dir.z * vel})
self._puncher = puncher
end,
collisionbox = def.collisionbox or {0, 0, 0, 0, 0, 0},

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

@ -564,6 +564,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

@ -126,14 +126,13 @@ mcl_mobs.register_arrow("mobs_mc:fireball", {
end,
hit_mob = function(self, mob)
local name = mob:get_luaentity().name
mob:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 6},
}, nil)
mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1, true)
local ent = mob:get_luaentity()
if (not ent or ent.health <= 0) and self._puncher and name == "mobs_mc:ghast" then
if not ent or ent.health <= 0 then
awards.unlock(self._puncher:get_player_name(), "mcl:fireball_redir_serv")
end
end,

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

@ -106,31 +106,6 @@ local item_lists = {
"craftpreview",
}
local function init_data(name)
player_data[name] = {
filter = "",
pagenum = 1,
iX = sfinv_only and 8 or DEFAULT_SIZE,
items = init_items,
items_raw = init_items,
lang_code = M.get_player_information(name).lang_code or 'en',
}
end
local function get_player_data(name)
-- If the data alrady exists, use it
local data = player_data[name]
if data then return data end
-- Initialize player data if it doesn't exist
init_data(name)
local player = minetest.get_player_by_name(name)
local meta = player:get_meta()
local data = player_data[name]
data.inv_items = deserialize(meta:get_string("inv_items")) or {}
return data
end
local function table_merge(t, t2)
t, t2 = t or {}, t2 or {}
local c = #t
@ -649,7 +624,7 @@ local function get_recipe_fs(data, iY)
end
local function make_formspec(name)
local data = get_player_data(name)
local data = player_data[name]
local iY = sfinv_only and 4 or data.iX - 5
local ipp = data.iX * iY
@ -856,6 +831,17 @@ local function get_inv_items(player)
return inv_items
end
local function init_data(name)
player_data[name] = {
filter = "",
pagenum = 1,
iX = sfinv_only and 8 or DEFAULT_SIZE,
items = init_items,
items_raw = init_items,
lang_code = M.get_player_information(name).lang_code or 'en',
}
end
local function reset_data(data)
data.filter = ""
data.pagenum = 1
@ -891,7 +877,7 @@ end
local function on_receive_fields(player, fields)
local name = player:get_player_name()
local data = get_player_data(name)
local data = player_data[name]
for elem_name, def in pairs(formspec_elements) do
if fields[elem_name] and def.action then
@ -995,7 +981,7 @@ if sfinv_only then
on_enter = function(self, player, context)
if next(recipe_filters) then
local name = player:get_player_name()
local data = get_player_data(name)
local data = player_data[name]
data.items_raw = get_filtered_items(player)
search(data)
@ -1019,7 +1005,7 @@ else
local name = user:get_player_name()
if next(recipe_filters) then
local data = get_player_data(name)
local data = player_data[name]
data.items_raw = get_filtered_items(user)
search(data)
end
@ -1065,7 +1051,7 @@ if progressive_mode then
local function progressive_filter(recipes, player)
local name = player:get_player_name()
local data = get_player_data(name)
local data = player_data[name]
if #data.inv_items == 0 then
return {}
@ -1090,7 +1076,7 @@ if progressive_mode then
for i = 1, #players do
local player = players[i]
local name = player:get_player_name()
local data = get_player_data(name)
local data = player_data[name]
local inv_items = get_inv_items(player)
local diff = table_diff(inv_items, data.inv_items)
@ -1109,7 +1095,12 @@ if progressive_mode then
mcl_craftguide.add_recipe_filter("Default progressive filter", progressive_filter)
M.register_on_joinplayer(function(player)
get_player_data(player:get_player_name())
local name = player:get_player_name()
init_data(name)
local meta = player:get_meta()
local data = player_data[name]
data.inv_items = deserialize(meta:get_string("inv_items")) or {}
end)
local function save_meta(player)
@ -1154,7 +1145,7 @@ end
function mcl_craftguide.show(name)
local player = get_player_by_name(name)
if next(recipe_filters) then
local data = get_player_data(name)
local data = player_data[name]
data.items_raw = get_filtered_items(player)
search(data)
end

View File

@ -45,4 +45,4 @@ Mining durability: @1=Wytrzymałość kopania: @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

@ -46,3 +46,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

@ -112,3 +112,58 @@ tt.register_snippet(function(itemstring, _, itemstack)
return S("Durability: @1", S("@1 uses", mcl_util.calculate_durability(itemstack or ItemStack(itemstring))))
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

@ -36,14 +36,9 @@ function mcl_inventory.register_survival_inventory_tab(def)
end
local player_current_tab = {}
function get_player_tab(player)
local tab = player_current_tab[player] or "main"
player_current_tab[player] = tab
return tab
end
minetest.register_on_joinplayer(function(player, last_login)
get_player_tab(player)
player_current_tab[player] = "main"
end)
minetest.register_on_leaveplayer(function(player, timed_out)
@ -189,7 +184,7 @@ function mcl_inventory.build_survival_formspec(player)
inv:set_width("craft", 2)
inv:set_size("craft", 4)
local tab = get_player_tab(player)
local tab = player_current_tab[player]
local tab_def = nil
@ -218,7 +213,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
for _, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do
if get_player_tab(player) == d.id and d.access(player) then
if player_current_tab[player] == d.id and d.access(player) then
d.handle(player, fields)
return
end

View File

@ -16,31 +16,19 @@ local function offhand_get_count(player)
return mcl_offhand.get_offhand(player):get_count()
end
local function get_offhand(player)
-- Get offhand data if it already exists
local offhand = mcl_offhand[player]
if offhand then return offhand end
-- Otherwise initialize it
offhand = {
minetest.register_on_joinplayer(function(player, last_login)
mcl_offhand[player] = {
hud = {},
last_wear = offhand_get_wear(player),
last_count = offhand_get_count(player),
}
mcl_offhand[player] = offhand
return offhand
end
minetest.register_on_joinplayer(function(player, last_login)
get_offhand(player)
end)
local function remove_hud(player, hud)
local offhand = get_offhand(player)
local offhand_hud = offhand.hud[hud]
local offhand_hud = mcl_offhand[player].hud[hud]
if offhand_hud then
player:hud_remove(offhand_hud)
offhand.hud[hud] = nil
mcl_offhand[player].hud[hud] = nil
end
end
@ -60,8 +48,7 @@ local function update_wear_bar(player, itemstack)
else
color = {255, 511 - wear_i, 0}
end
local offhand = get_offhand(player)
local wear_bar = offhand.hud.wear_bar
local wear_bar = mcl_offhand[player].hud.wear_bar
player:hud_change(wear_bar, "text", "mcl_wear_bar.png^[colorize:#" .. rgb_to_hex(color[1], color[2], color[3]))
player:hud_change(wear_bar, "scale", {x = 40 * wear_bar_percent, y = 3})
player:hud_change(wear_bar, "offset", {x = -320 - (20 - player:hud_get(wear_bar).scale.x / 2), y = -13})
@ -71,8 +58,7 @@ minetest.register_globalstep(function(dtime)
for _, player in pairs(minetest.get_connected_players()) do
local itemstack = mcl_offhand.get_offhand(player)
local offhand_item = itemstack:get_name()
local offhand = get_offhand(player)
local offhand_hud = offhand.hud
local offhand_hud = mcl_offhand[player].hud
local item = minetest.registered_items[offhand_item]
if offhand_item ~= "" and item then
local item_texture = item.inventory_image .. "^[resize:" .. max_offhand_px .. "x" .. max_offhand_px
@ -159,8 +145,7 @@ minetest.register_globalstep(function(dtime)
end
elseif offhand_hud.slot then
local offhand = get_offhand(player)
for index, _ in pairs(offhand.hud) do
for index, _ in pairs(mcl_offhand[player].hud) do
remove_hud(player, index)
end
end

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

@ -8,7 +8,7 @@ local is_sp = minetest.is_singleplayer()
local weather_mod = minetest.get_modpath("mcl_weather")
local explosions_mod = minetest.get_modpath("mcl_explosions")
local spawn_mod = minetest.get_modpath("mcl_spawn")
local pos_to_dim = minetest.get_modpath("mcl_worlds") and mcl_worlds.pos_to_dimension or function(pos) return "overworld" end
local worlds_mod = minetest.get_modpath("mcl_worlds")
local function mcl_log (message)
mcl_util.mcl_log (message, "[Beds]")
@ -38,16 +38,6 @@ local function is_night_skip_enabled()
return players_in_bed_setting() <= 100
end
local function players_in_overworld(players)
local count = 0
for _, player in pairs(players) do
if player and pos_to_dim(player:get_pos()) == "overworld" then
count = count +1
end
end
return count
end
local function check_in_beds(players)
if not players then
players = minetest.get_connected_players()
@ -55,7 +45,7 @@ local function check_in_beds(players)
if player_in_bed <= 0 then
return false
end
return players_in_bed_setting() <= (player_in_bed * 100) / players_in_overworld(players)
return players_in_bed_setting() <= (player_in_bed * 100) / #players
end
-- These monsters do not prevent sleep
@ -216,10 +206,10 @@ local function lay_down(player, pos, bed_pos, state, skip)
return true
end
local function update_formspecs(finished, players)
local ges = players_in_overworld(players or minetest.get_connected_players())
local function update_formspecs(finished, ges)
local ges = ges or #minetest.get_connected_players()
local form_n = "size[12,5;true]"
local all_in_bed = ges and players_in_bed_setting() <= (player_in_bed * 100) / ges or 0
local all_in_bed = players_in_bed_setting() <= (player_in_bed * 100) / ges
local night_skip = is_night_skip_enabled()
local button_leave = "button_exit[4,3;4,0.75;leave;"..F(S("Leave bed")).."]"
local button_abort = "button_exit[4,3;4,0.75;leave;"..F(S("Abort sleep")).."]"
@ -359,25 +349,13 @@ function mcl_beds.get_bed_bottom (pos)
return bed_bottom
end
local function recheck_in_beds()
if check_in_beds() then
update_formspecs(is_night_skip_enabled())
mcl_beds.sleep()
end
-- check again (a player can change the dimension)
if player_in_bed > 0 then
update_formspecs(false)
minetest.after(5, recheck_in_beds)
end
end
function mcl_beds.on_rightclick(pos, player, is_top)
-- Anti-Inception: Don't allow to sleep while you're sleeping
if player:get_meta():get_string("mcl_beds:sleeping") == "true" then
return
end
local dim = pos_to_dim(pos)
if worlds_mod then
local dim = mcl_worlds.pos_to_dimension(pos)
if dim == "nether" or dim == "end" then
-- Bed goes BOOM in the Nether or End.
local node = minetest.get_node(pos)
@ -390,6 +368,7 @@ function mcl_beds.on_rightclick(pos, player, is_top)
end
return
end
end
local name = player:get_player_name()
local ppos = player:get_pos()
@ -406,13 +385,10 @@ function mcl_beds.on_rightclick(pos, player, is_top)
mcl_title.set(player, "actionbar", {text=message, color="white", stay=60})
else -- someone just successfully entered a bed
local connected_players = minetest.get_connected_players()
local ges = players_in_overworld(connected_players)
local sleep_hud_message = S("@1/@2 players currently in bed.", player_in_bed, math.ceil(players_in_bed_setting() * ges / 100))
local sleep_hud_message = S("@1/@2 players currently in bed.", player_in_bed, math.ceil(players_in_bed_setting() * #connected_players / 100))
for _, player in pairs(connected_players) do
-- only send message to players not sleeping and in the "overworld"
if not mcl_beds.player[player:get_player_name()] and pos_to_dim(player:get_pos()) == "overworld" then
-- clear, old message is still being displayed
if mcl_title.params_get(player) then mcl_title.clear(player) end
if not mcl_beds.player[player:get_player_name()] then -- only send message to players not sleeping.
if mcl_title.params_get(player) then mcl_title.clear(player) end -- clear, old message is still being displayed
mcl_title.set(player, "actionbar", {text=sleep_hud_message, color="white", stay=60})
end
end
@ -424,8 +400,13 @@ function mcl_beds.on_rightclick(pos, player, is_top)
update_formspecs(false)
-- skip the night and let all players stand up
if player_in_bed > 0 then
minetest.after(5, recheck_in_beds)
if check_in_beds() then
minetest.after(5, function()
if check_in_beds() then
update_formspecs(is_night_skip_enabled())
mcl_beds.sleep()
end
end)
end
end
@ -452,10 +433,15 @@ minetest.register_on_leaveplayer(function(player)
break
end
end
if player_in_bed > 0 then
minetest.after(5, recheck_in_beds)
if check_in_beds(players) then
minetest.after(5, function()
if check_in_beds() then
update_formspecs(is_night_skip_enabled())
mcl_beds.sleep()
end
update_formspecs(false, players)
end)
end
update_formspecs(false, #players)
end)
local message_rate_limit = tonumber(minetest.settings:get("chat_message_limit_per_10sec")) or 8 --NEVER change this! if this was java, i would've declared it as final

View File

@ -8,60 +8,36 @@ local S = minetest.get_translator(minetest.get_current_modname())
-- Function to allow harvesting honey and honeycomb from the beehive and bee nest.
local honey_harvest = function(pos, node, player, itemstack, pointed_thing)
local inv = player:get_inventory()
local item = player:get_wielded_item()
local shears = minetest.get_item_group(player:get_wielded_item():get_name(), "shears") > 0
local bottle = player:get_wielded_item():get_name() == "mcl_potions:glass_bottle"
local beehive = "mcl_beehives:beehive"
local is_creative = minetest.is_creative_enabled(player:get_player_name())
-- Determine the node name to replace the beehive with if harvest is successful
local beehive = "mcl_beehives:beehive"
if node.name == "mcl_beehives:beehive_5" then
beehive = "mcl_beehives:beehive"
elseif node.name == "mcl_beehives:bee_nest_5" then
beehive = "mcl_beehives:bee_nest"
end
-- Check for a campfire within 5 blocks below the beehive
local campfire_area = vector.offset(pos, 0, -5, 0)
local campfire = minetest.find_nodes_in_area(pos, campfire_area, "group:lit_campfire")
-- Player used a bottle
if item:get_name() == "mcl_potions:glass_bottle" then
if bottle then
local honey = "mcl_honey:honey_bottle"
if inv:room_for_item("main", honey) then
-- Replace the beehive with the version without honey or comb
node.name = beehive
minetest.set_node(pos, node)
-- Give honey bottle and take the empty bottle if survival mode
inv:add_item("main", "mcl_honey:honey_bottle")
if not is_creative then
itemstack:take_item()
end
-- Hurt the player if there was no campfire, or give award if there was
if not campfire[1] then
mcl_util.deal_damage(player, 10)
else
awards.unlock(player:get_player_name(), "mcl:bee_our_guest")
if not campfire[1] then mcl_util.deal_damage(player, 10) else awards.unlock(player:get_player_name(), "mcl:bee_our_guest") end
end
end
-- Player used shears
elseif minetest.get_item_group(item:get_name(), "shears") > 0 then
-- Give honeycomb
elseif shears then
minetest.add_item(pos, "mcl_honey:honeycomb 3")
-- Replace the beehive with the version without honey or comb
node.name = beehive
minetest.set_node(pos, node)
-- Hurt the player if there was no campfire
if not campfire[1] then mcl_util.deal_damage(player, 10) end
-- Add wear to the shears
if not is_creative then
mcl_util.use_item_durability(item, 1)
return item
end
end
end

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

@ -379,7 +379,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

@ -61,8 +61,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({
@ -113,6 +113,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,
@ -516,7 +518,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

@ -638,7 +638,7 @@ function mcl_itemframes.create_base_definitions()
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
groups = { dig_immediate = 3, deco_block = 1, dig_by_piston = 1, container = 1, attached_node_facedir = 1 },
groups = { dig_immediate = 3, deco_block = 1, dig_by_piston = 1, container = 1, }, -- attached_node_facedir = 1 }, -- allows for more placement options.
sounds = mcl_sounds.node_sound_defaults(),
node_placement_prediction = "",

View File

@ -141,7 +141,7 @@ local function drink_milk(itemstack, player, pointed_thing)
if mcl_hunger.active and (bucket:get_name() ~= "mcl_mobitems:milk_bucket" or minetest.is_creative_enabled(player:get_player_name())) then
mcl_hunger.stop_poison(player)
end
mcl_potions._reset_player_effects(player)
mcl_potions._reset_effects(player)
return bucket
end
@ -165,7 +165,7 @@ local function drink_milk_delayed(itemstack, player, pointed_thing)
if mcl_hunger.active and (player:get_inventory():get_stack("main", player:get_wield_index(), itemstack) == "mcl_mobitems:milk_bucket" or minetest.is_creative_enabled(player:get_player_name())) then
mcl_hunger.stop_poison(player)
end
mcl_potions._reset_player_effects(player)
mcl_potions._reset_effects(player)
return bucket
end
@ -245,6 +245,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."),
@ -594,6 +634,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
mundane_table[ingr] = potion
end
mcl_potions.register_ingredient_potion("mcl_potions:mundane", mundane_table)
for i, potion in ipairs({"awkward", "mundane", "thick", "water"}) do
table.insert(potions, potion)
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:enderman" 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

@ -251,15 +251,6 @@ local function remove_shield_entity(player, i)
end
end
local function is_node_stack(itemstack)
return itemstack:get_definition().drawtype -- only node's definition table contains element "drawtype"
end
local function is_rmb_conflicting_node(nodename)
local nodedef = minetest.registered_nodes[nodename]
return nodedef.on_rightclick
end
local function handle_blocking(player)
local player_shield = mcl_shields.players[player]
local rmb = player:get_player_control().RMB
@ -275,7 +266,7 @@ local function handle_blocking(player)
local pos = player:get_pos()
if shield_in_hand then
if not_blocking then
minetest.after(0.05, function()
minetest.after(0.25, function()
if (not_blocking or not shield_in_offhand) and shield_in_hand and rmb then
player_shield.blocking = 2
set_shield(player, true, 2)
@ -286,16 +277,11 @@ local function handle_blocking(player)
end
elseif shield_in_offhand then
local pointed_thing = mcl_util.get_pointed_thing(player, true)
local wielded_stack = player:get_wielded_item()
local offhand_can_block = (minetest.get_item_group(wielded_item(player), "bow") ~= 1
and minetest.get_item_group(wielded_item(player), "crossbow") ~= 1)
local offhand_can_block = (wielded_item(player) == "" or not pointed_thing)
and (minetest.get_item_group(wielded_item(player), "bow") ~= 1 and minetest.get_item_group(wielded_item(player), "crossbow") ~= 1)
if pointed_thing and pointed_thing.type == "node" then
local pointed_node = minetest.get_node(pointed_thing.under)
if minetest.get_item_group(pointed_node.name, "container") > 1
or is_rmb_conflicting_node(pointed_node.name)
or is_node_stack(wielded_stack)
then
if minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "container") > 1 then
return
end
end
@ -304,7 +290,7 @@ local function handle_blocking(player)
return
end
if not_blocking then
minetest.after(0.05, function()
minetest.after(0.25, function()
if (not_blocking or not shield_in_hand) and shield_in_offhand and rmb and offhand_can_block then
player_shield.blocking = 1
set_shield(player, true, 1)

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

@ -1,28 +0,0 @@
# ```vl_hollow_logs```
This mod registers hollow logs derived from normal logs.
Hollow logs mostly have a decorative function, but some of them can be used in recipes. Changes may appear soon.
## Functions:
### ```vl_hollow_logs.register_hollow_log(defs)```
This is the function that registers the hollow trunk.
For a hollow log to be registered, the <span style="color:firebrick"> defs </span> parameter must be a table that contains up to 5 values, which are, in this order, the <span style="color:firebrick"> itemstring </span> of the hollow log, the <span style="color:firebrick"> itemstring </span> of the stripped hollow log, the <span style="color:firebrick"> description </span> of the hollow log, the <span style="color:firebrick"> description </span> of the stripped hollow log and, optionally, a <span style="color:turquoise"> boolean </span> to inform whether this trunk is NOT flammable. If the hollow log is defined as flammable, it becomes part of the <span style="color:springgreen"> hollow_log_flammable </span> group, which allows the log to be used as fuel for furnaces and also allows it to be an ingredient for chacoal.
Examples:
```lua
-- Flammable
{"tree", "stripped_oak", "Hollow Oak Log", "Stripped Hollow Oak Log"}
-- Not flammable
{"crimson_hyphae", "stripped_crimson_hyphae", "Hollow Crimson Stem", "Stripped Hollow Crimson Stem", true}
```
### ```vl_hollow_logs.register_craft(material, result)```
This function records the crafting recipe for a hollow log based on its non-hollow variant.
This function also defines a recipe for the stonecutter. The <span style="color:firebrick"> material </span> and <span style="color:firebrick"> result </span> parameters must be, respectively, the <span style="color:firebrick"> complete itemstring </span> of the source material and the (partial) <span style="color:firebrick"> itemstring </span> of the result. See the following examples:
```lua
vl_hollow_logs.register_craft("mcl_core:tree", "tree")
vl_hollow_logs.register_craft("mcl_crimson:stripped_crimson_hyphae", "stripped_crimson_hyphae")
```

View File

@ -1,112 +0,0 @@
local modpath = minetest.get_modpath(minetest.get_current_modname())
local S = minetest.get_translator(minetest.get_current_modname())
vl_hollow_logs = {}
--- Function to register a hollow log. See API.md to learn how to use this function.
---@param defs table {name:string, stripped_name>string, desc:string, stripped_desc:string, not_flammable:boolean|nil}
function vl_hollow_logs.register_hollow_log(defs)
if not defs or #defs < 4 then
error("Incomplete definition provided")
end
for i = 1, 4 do
if type(defs[i]) ~= "string" then
error("defs["..i.."] must be a string")
end
end
if defs[5] and type(defs[5]) ~= "boolean" then
error("defs[5] must be a boolean if present")
end
local modname = minetest.get_current_modname()
if #defs > 5 then
minetest.log("warning", "[vl_hollow_logs] unused vars passed, dumping the table")
minetest.log("warning", "from mod " .. modname .. ": " .. dump(defs))
end
local name = defs[1]
local stripped_name = defs[2]
local desc = defs[3]
local stripped_desc = defs[4]
local collisionbox = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.5, -0.375},
{-0.5, -0.5, -0.5, -0.375, 0.5, 0.5},
{0.375, -0.5, -0.5, 0.5, 0.5, 0.5},
{-0.5, -0.5, 0.375, 0.5, 0.5, 0.5},
}
}
local groups = {axey = 1, building_block = 1, handy = 1, hollow_log = 1}
if not defs[5] then
groups = table.insert(groups, {fire_encouragement = 5, fire_flammability = 5, flammable = 2, hollow_log_burnable = 1})
end
minetest.register_node(modname .. ":"..name.."_hollow", {
collision_box = collisionbox,
description = S(desc),
drawtype = "mesh",
groups = groups,
mesh = "vl_hollow_logs_log.obj",
on_place = mcl_util.rotate_axis,
paramtype = "light",
paramtype2 = "facedir",
use_texture_alpha = "clip",
sounds = mcl_sounds.node_sound_wood_defaults(),
sunlight_propagates = true,
tiles = {modname .. "_"..name..".png"},
_mcl_blast_resistance = 2,
_mcl_hardness = 2,
_mcl_stripped_variant = modname .. ":stripped_"..name.."_hollow"
})
minetest.register_node(modname .. ":"..stripped_name.."_hollow", {
collision_box = collisionbox,
description = S(stripped_desc),
drawtype = "mesh",
groups = groups,
mesh = "vl_hollow_logs_log.obj",
on_place = mcl_util.rotate_axis,
paramtype = "light",
paramtype2 = "facedir",
use_texture_alpha = "clip",
sounds = mcl_sounds.node_sound_wood_defaults(),
sunlight_propagates = true,
tiles = {modname .. "_stripped_"..name..".png"},
_mcl_blast_resistance = 2,
_mcl_hardness = 2
})
end
vl_hollow_logs.logs = {
{"acaciatree", "stripped_acacia", "Hollow Acacia Log", "Stripped Hollow Acacia Log"},
{"birchtree", "stripped_birch", "Hollow Birch Log", "Stripped Hollow Birch Log"},
{"darktree", "stripped_dark_oak", "Hollow Dark Oak Log", "Stripped Hollow Dark Oak Log"},
{"jungletree", "stripped_jungle", "Hollow Jungle Log", "Stripped Hollow Jungle Log"},
{"sprucetree", "stripped_spruce", "Hollow Spruce Log", "Stripped Hollow Spruce Log"},
{"tree", "stripped_oak", "Hollow Oak Log", "Stripped Hollow Oak Log"}
}
if minetest.get_modpath("mcl_cherry_blossom") then
table.insert(vl_hollow_logs.logs, {"cherrytree", "stripped_cherrytree", "Hollow Cherry Log", "Stripped Hollow Cherry Log"})
end
if minetest.get_modpath("mcl_mangrove") then
table.insert(vl_hollow_logs.logs, {"mangrove_tree", "mangrove_stripped", "Hollow Mangrove Log", "Stripped Hollow Mangrove Log"})
end
if minetest.get_modpath("mcl_crimson") then
table.insert(vl_hollow_logs.logs, {"crimson_hyphae", "stripped_crimson_hyphae", "Hollow Crimson Stem", "Stripped Hollow Crimson Stem", true})
table.insert(vl_hollow_logs.logs, {"warped_hyphae", "stripped_warped_hyphae", "Hollow Warped Stem", "Stripped Hollow Warped Stem", true})
end
for _, defs in pairs(vl_hollow_logs.logs) do
vl_hollow_logs.register_hollow_log(defs)
end
dofile(modpath.."/recipes.lua")

View File

@ -1,21 +0,0 @@
# textdomain: mcl_hollow_logs
Hollow Acacia Log=
Hollow Birch Log=
Hollow Cherry Log=
Hollow Dark Oak Log=
Hollow Jungle Log=
Hollow Mangrove Log=
Hollow Oak Log=
Hollow Spruce Log=
Hollow Crimson Stem=
Hollow Warped Stem=
Stripped Hollow Acacia Log=
Stripped Hollow Birch Log=
Stripped Hollow Cherry Log=
Stripped Hollow Dark Oak Log=
Stripped Hollow Jungle Log=
Stripped Hollow Mangrove Log=
Stripped Hollow Oak Log=
Stripped Hollow Spruce Log=
Stripped Hollow Crimson Stem=
Stripped Hollow Warped Stem=

View File

@ -1,21 +0,0 @@
# textdomain: mcl_hollow_logs
Hollow Acacia Log=Tronco Oco de Acácia
Hollow Birch Log=Tronco Oco de Bétula
Hollow Cherry Log=Tronco Oco de Cerejeira
Hollow Dark Oak Log=Tronco Oco de Carvalho Escuro
Hollow Jungle Log=Tronco Oco da Selva
Hollow Mangrove Log=Tronco Oco de Mangue
Hollow Oak Log=Tronco Oco de Carvalho
Hollow Spruce Log=Tronco Oco de Pinheiro
Hollow Crimson Stem=Caule Oco Carmesim
Hollow Warped Stem=Caule Oco Distorcido
Stripped Hollow Acacia Log=Tronco Oco Descascado de Acácia
Stripped Hollow Birch Log=Tronco Oco Descascado de Bétula
Stripped Hollow Cherry Log=Tronco Oco Descascado de Cerejeira
Stripped Hollow Dark Oak Log=Tronco Oco Descascado de Carvalho Escuro
Stripped Hollow Jungle Log=Tronco Oco Descascado da Selva
Stripped Hollow Mangrove Log=Tronco Oco Descascado de Mangue
Stripped Hollow Oak Log=Tronco Oco Descascado de Carvalho
Stripped Hollow Spruce Log=Tronco Oco Descascado de Pinheiro
Stripped Hollow Crimson Stem=Caule Oco Descascado Carmesim
Stripped Hollow Warped Stem=Caule Oco Descascado Distorcido

View File

@ -1,4 +0,0 @@
name = vl_hollow_logs
depends = mcl_core, mcl_sounds, mcl_util
optional_depends = mcl_cherry_blossom, mcl_crimson, mcl_mangrove
author = JoseDouglas26

View File

@ -1,54 +0,0 @@
# Blender 3.6.7
# www.blender.org
o hollow_log
v -0.312500 -0.500000 0.312500
v -0.312500 0.500000 0.312500
v -0.312500 -0.500000 -0.312500
v -0.312500 0.500000 -0.312500
v 0.312500 -0.500000 0.312500
v 0.312500 0.500000 0.312500
v 0.312500 -0.500000 -0.312500
v 0.312500 0.500000 -0.312500
v -0.500000 -0.500000 -0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v 0.500000 0.500000 0.500000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.380952 0.000000
vt 0.380952 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 0.619048 0.000000
vt 0.619048 1.000000
vt 0.928571 0.187500
vt 0.928571 0.812500
vt 1.000000 1.000000
vt 1.000000 -0.000000
vt 0.690476 0.187500
vt 0.690476 0.812500
s 0
f 10/1/1 11/2/1 12/3/1 9/4/1
f 9/1/2 12/2/2 14/3/2 13/4/2
f 13/1/3 14/2/3 16/3/3 15/4/3
f 15/1/4 16/2/4 11/3/4 10/4/4
f 7/5/4 8/6/4 4/2/4 3/1/4
f 5/5/1 6/6/1 8/2/1 7/1/1
f 3/7/5 1/8/5 10/9/5 9/10/5
f 2/8/6 4/7/6 12/10/6 11/9/6
f 7/11/5 3/7/5 9/10/5 13/5/5
f 4/7/6 8/11/6 14/5/6 12/10/6
f 5/12/5 7/11/5 13/5/5 15/6/5
f 8/11/6 6/12/6 16/6/6 14/5/6
f 1/8/5 5/12/5 15/6/5 10/9/5
f 6/12/6 2/8/6 11/9/6 16/6/6
f 3/5/3 4/6/3 2/2/3 1/1/3
f 1/5/2 2/6/2 6/2/2 5/1/2

View File

@ -1,48 +0,0 @@
function vl_hollow_logs.register_craft(material, result)
minetest.register_craft({
output = "vl_hollow_logs:"..result.."_hollow 4",
recipe = {
{"", material, ""},
{material, "", material},
{"", material, ""}
},
type = "shaped"
})
mcl_stonecutter.register_recipe(material, "vl_hollow_logs:"..result.."_hollow", 1)
end
for _, defs in pairs(vl_hollow_logs.logs) do
local mod, material, stripped_material
local name = defs[1]
local stripped_name = defs[2]
if name:find("cherry") then
mod = "mcl_cherry_blossom:"
elseif name:find("mangrove") then
mod = "mcl_mangrove:"
elseif name:find("hyphae") then
mod = "mcl_crimson:"
else
mod = "mcl_core:"
end
material = mod..name
stripped_material = mod..stripped_name
vl_hollow_logs.register_craft(material, name)
vl_hollow_logs.register_craft(stripped_material, stripped_name)
end
minetest.register_craft({
burntime = 10,
recipe = "group:hollow_log_burnable",
type = "fuel",
})
minetest.register_craft({
cooktime = 5,
output = "mcl_core:charcoal_lump",
recipe = "group:hollow_log_burnable",
type = "cooking"
})

View File

@ -406,8 +406,6 @@ local function dungeons_nodes(minp, maxp, blockseed)
local pr = PseudoRandom(blockseed)
for a=1, attempts do
local dim = dungeonsizes[pr:next(1, #dungeonsizes)]
if ymin <= ymax - dim.y - 1 then
local x = pr:next(minp.x, maxp.x-dim.x-1)
local y = pr:next(ymin , ymax -dim.y-1)
local z = pr:next(minp.z, maxp.z-dim.z-1)
@ -416,7 +414,6 @@ local function dungeons_nodes(minp, maxp, blockseed)
minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2))
emerge_area(p1, p2, ecb_spawn_dungeon, {p1=p1, p2=p2, dim=dim, pr=pr})
end
end
end
function mcl_dungeons.spawn_dungeon(p1, _, pr)

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)

View File

@ -38,19 +38,9 @@ local player_sneak = {}
local player_visible = {}
mcl_player.player_attached = {}
local function get_player_textures(name)
local textures = player_textures[name]
if textures then return textures end
local textures = { "character.png", "blank.png", "blank.png" }
player_textures[name] = textures
return textures
end
function mcl_player.player_get_animation(player)
local name = player:get_player_name()
local textures = get_player_textures(name)
local textures = player_textures[name]
if not player_visible[name] then
textures = table.copy(textures)
@ -73,7 +63,7 @@ end
local function update_player_textures(player)
local name = player:get_player_name()
local textures = get_player_textures(name)
local textures = player_textures[name]
if not player_visible[name] then
textures = table.copy(textures)
@ -135,21 +125,18 @@ end
function mcl_player.player_set_skin(player, texture)
local name = player:get_player_name()
local textures = get_player_textures(name)
textures[1] = texture
player_textures[name][1] = texture
update_player_textures(player)
end
function mcl_player.player_get_skin(player)
local name = player:get_player_name()
local textures = get_player_textures(name)
return textures[1]
return player_textures[name][1]
end
function mcl_player.player_set_armor(player, texture)
local name = player:get_player_name()
local textures = get_player_textures(name)
textures[2] = texture
player_textures[name][2] = texture
update_player_textures(player)
end
@ -164,7 +151,7 @@ function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname)
local name = player:get_player_name()
local model = player_model[name]
local anim = models[model].animations[player_anim[name]]
local textures = get_player_textures(name)
local textures = player_textures[name]
if not player_visible[name] then
textures = table.copy(textures)
textures[1] = "blank.png"
@ -192,7 +179,7 @@ minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
mcl_player.player_attached[name] = false
player_visible[name] = true
get_player_textures(name)
player_textures[name] = { "character.png", "blank.png", "blank.png" }
--player:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30)
-- player:set_fov(86.1) -- see <https://minecraft.gamepedia.com/Options#Video_settings>>>>

View File

@ -59,50 +59,6 @@ mcl_skins = {
player_formspecs = {},
}
local player_skins = mcl_skins.player_skins
local function get_player_skins(player)
local player_skins = player_skins[player]
if player_skins then return player_skins end
local skin = player:get_meta():get_string("mcl_skins:skin")
if skin then
skin = minetest.deserialize(skin)
end
if skin then
if not mcl_skins.texture_to_simple_skin[skin.simple_skins_id] then
skin.simple_skins_id = nil
end
mcl_skins.player_skins[player] = skin
else
if math.random() > 0.5 then
skin = table.copy(mcl_skins.template1)
else
skin = table.copy(mcl_skins.template2)
end
mcl_skins.player_skins[player] = skin
end
mcl_skins.player_formspecs[player] = {
active_tab = "skin",
page_num = 1
}
if #mcl_skins.simple_skins > 0 then
local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id"))
if skin_id and mcl_skins.simple_skins[skin_id] then
local texture = mcl_skins.simple_skins[skin_id].texture
local player_skins = get_player_skins(player)
player_skins.simple_skins_id = texture
end
end
mcl_skins.save(player)
mcl_skins.update_player_skin(player)
return mcl_skins.player_skins[player]
end
function mcl_skins.register_item(item)
assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.")
@ -204,7 +160,7 @@ function mcl_skins.update_player_skin(player)
return
end
local skin = get_player_skins(player)
local skin = mcl_skins.player_skins[player]
local skinval = mcl_skins.compile_skin(skin)
if not skin.cape then skin.cape = "blank.png" end
@ -230,7 +186,39 @@ end
-- Load player skin on join
minetest.register_on_joinplayer(function(player)
get_player_skins(player)
local skin = player:get_meta():get_string("mcl_skins:skin")
if skin then
skin = minetest.deserialize(skin)
end
if skin then
if not mcl_skins.texture_to_simple_skin[skin.simple_skins_id] then
skin.simple_skins_id = nil
end
mcl_skins.player_skins[player] = skin
else
if math.random() > 0.5 then
skin = table.copy(mcl_skins.template1)
else
skin = table.copy(mcl_skins.template2)
end
mcl_skins.player_skins[player] = skin
end
mcl_skins.player_formspecs[player] = {
active_tab = "skin",
page_num = 1
}
if #mcl_skins.simple_skins > 0 then
local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id"))
if skin_id and mcl_skins.simple_skins[skin_id] then
local texture = mcl_skins.simple_skins[skin_id].texture
mcl_skins.player_skins[player].simple_skins_id = texture
end
end
mcl_skins.save(player)
mcl_skins.update_player_skin(player)
end)
minetest.register_on_leaveplayer(function(player)
@ -257,7 +245,7 @@ end
function mcl_skins.show_formspec(player, active_tab, page_num)
local formspec_data = mcl_skins.player_formspecs[player]
local skin = get_player_skins(player)
local skin = mcl_skins.player_skins[player]
formspec_data.active_tab = active_tab
local page_count = calculate_page_count(active_tab, player)
@ -567,8 +555,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
mcl_skins.show_formspec(player, active_tab, page_num)
return true
elseif fields.nocape then
local player_skins = get_player_skins(player)
player_skins.cape = "blank.png"
mcl_skins.player_skins[player].cape = "blank.png"
mcl_skins.update_player_skin(player)
mcl_armor.update(player) --update elytra cape
mcl_skins.show_formspec(player, active_tab, page_num)
@ -577,8 +564,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
for cape_index = ((page_num - 1) * 5) + 1, math.min(#mcl_skins.cape, page_num * 5) do
local cape = mcl_skins.cape[cape_index]
if fields[cape.name] then
local player_skins = get_player_skins(player)
player_skins.cape = cape.mask -- the actual overlay image
mcl_skins.player_skins[player].cape = cape.mask -- the actual overlay image
mcl_skins.update_player_skin(player)
mcl_armor.update(player) --update elytra cape
mcl_skins.show_formspec(player, active_tab, page_num)
@ -594,7 +580,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
end
local skin = get_player_skins(player)
local skin = mcl_skins.player_skins[player]
if not skin then return true end
if fields.next_page then

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 B

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 261 B

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

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