forked from VoxeLibre/VoxeLibre
Merge branch 'master' into shields
This commit is contained in:
commit
e972265762
|
@ -0,0 +1,15 @@
|
||||||
|
# mcl_damage
|
||||||
|
|
||||||
|
This mod is intended to overall minetest's native damage system, to provide a better integration between features that deals with entities' health.
|
||||||
|
|
||||||
|
WARNING: Not using it inside your mods may cause strange bugs (using the native damage system may cause conflicts with this system).
|
||||||
|
|
||||||
|
## Callbacks
|
||||||
|
|
||||||
|
To modify the amount of damage made by something:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
--obj: an ObjectRef
|
||||||
|
mcl_damage.register_modifier(function(obj, damage, reason)
|
||||||
|
end, 0)
|
||||||
|
```
|
|
@ -571,3 +571,16 @@ function mcl_util.replace_mob(obj, mob)
|
||||||
obj:set_yaw(rot)
|
obj:set_yaw(rot)
|
||||||
return obj
|
return obj
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mcl_util.get_pointed_thing(player, liquid)
|
||||||
|
local pos = vector.offset(player:get_pos(), 0, player:get_properties().eye_height, 0)
|
||||||
|
local look_dir = vector.multiply(player:get_look_dir(), 5)
|
||||||
|
local pos2 = vector.add(pos, look_dir)
|
||||||
|
local ray = minetest.raycast(pos, pos2, false, liquid)
|
||||||
|
|
||||||
|
if ray then
|
||||||
|
for pointed_thing in ray do
|
||||||
|
return pointed_thing
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -267,7 +267,7 @@ function boat.on_step(self, dtime, moveresult)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local yaw = self.object:get_yaw()
|
local yaw = self.object:get_yaw()
|
||||||
if ctrl.up then
|
if ctrl and ctrl.up then
|
||||||
-- Forwards
|
-- Forwards
|
||||||
self._v = self._v + 0.1 * v_factor
|
self._v = self._v + 0.1 * v_factor
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ function boat.on_step(self, dtime, moveresult)
|
||||||
self.object:set_animation({x=0, y=40}, paddling_speed, 0, true)
|
self.object:set_animation({x=0, y=40}, paddling_speed, 0, true)
|
||||||
self._animation = 1
|
self._animation = 1
|
||||||
end
|
end
|
||||||
elseif ctrl.down then
|
elseif ctrl and ctrl.down then
|
||||||
-- Backwards
|
-- Backwards
|
||||||
self._v = self._v - 0.1 * v_factor
|
self._v = self._v - 0.1 * v_factor
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,298 @@
|
||||||
|
# mcl_armor
|
||||||
|
|
||||||
|
This mod implements the ability of registering armors.
|
||||||
|
|
||||||
|
## Registering an Armor Set
|
||||||
|
|
||||||
|
The `mcl_armor.register_set()` function aims to simplify the process of registering a full set of armor.
|
||||||
|
|
||||||
|
This function register four pieces of armor (head, torso, leggings, feets) based on a definition table:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
mcl_armor.register_set({
|
||||||
|
--name of the armor material (used for generating itemstrings)
|
||||||
|
name = "dummy_armor",
|
||||||
|
|
||||||
|
--description of the armor material
|
||||||
|
--do NOT translate this string, it will be concatenated will each piece of armor's description and result will be automatically fetched from your mod's translation files
|
||||||
|
description = "Dummy Armor",
|
||||||
|
|
||||||
|
--overide description of each armor piece
|
||||||
|
--do NOT localize this string
|
||||||
|
descriptions = {
|
||||||
|
head = "Cap", --default: "Helmet"
|
||||||
|
torso = "Tunic", --default: "Chestplate"
|
||||||
|
legs = "Pants", --default: "Leggings"
|
||||||
|
feet = "Shoes", --default: "Boots"
|
||||||
|
},
|
||||||
|
|
||||||
|
--this is used to calculate each armor piece durability with the minecraft algorithm
|
||||||
|
--head durability = durability * 0.6857 + 1
|
||||||
|
--torso durability = durability * 1.0 + 1
|
||||||
|
--legs durability = durability * 0.9375 + 1
|
||||||
|
--feet durability = durability * 0.8125 + 1
|
||||||
|
durability = 80,
|
||||||
|
|
||||||
|
--this is used then you need to specify the durability of each piece of armor
|
||||||
|
--this field have the priority over the durability one
|
||||||
|
--if the durability of some pieces of armor isn't specified in this field, the durability field will be used insteed
|
||||||
|
durabilities = {
|
||||||
|
head = 200,
|
||||||
|
torso = 500,
|
||||||
|
legs = 400,
|
||||||
|
feet = 300,
|
||||||
|
},
|
||||||
|
|
||||||
|
--this define how good enchants you will get then enchanting one piece of the armor in an enchanting table
|
||||||
|
--if set to zero or nil, the armor will not be enchantable
|
||||||
|
enchantability = 15,
|
||||||
|
|
||||||
|
--this define how much each piece of armor protect the player
|
||||||
|
--these points will be shown in the HUD (chestplate bar above the health bar)
|
||||||
|
points = {
|
||||||
|
head = 1,
|
||||||
|
torso = 3,
|
||||||
|
legs = 2,
|
||||||
|
feet = 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
--this attribute reduce strong damage even more
|
||||||
|
--See https://minecraft.fandom.com/wiki/Armor#Armor_toughness for more explanations
|
||||||
|
--default: 0
|
||||||
|
toughness = 2,
|
||||||
|
|
||||||
|
--this field is used to specify some items groups that will be added to each piece of armor
|
||||||
|
--please note that some groups do NOT need to be added by hand, because they are already handeled by the register function:
|
||||||
|
--(armor, combat_armor, armor_<element>, combat_armor_<element>, mcl_armor_points, mcl_armor_toughness, mcl_armor_uses, enchantability)
|
||||||
|
groups = {op_armor = 1},
|
||||||
|
|
||||||
|
--specify textures that will be overlayed on the entity wearing the armor
|
||||||
|
--these fields have default values and its recommanded to keep the code clean by just using the default name for your textures
|
||||||
|
textures = {
|
||||||
|
head = "dummy_texture.png", --default: "<modname>_helmet_<material>.png"
|
||||||
|
torso = "dummy_texture.png", --default: "<modname>_chestplate_<material>.png"
|
||||||
|
legs = "dummy_texture.png", --default: "<modname>_leggings_<material>.png"
|
||||||
|
feet = "dummy_texture.png", --default: "<modname>_boots_<material>.png"
|
||||||
|
},
|
||||||
|
--you can also define these fields as functions, that will be called each time the API function mcl_armor.update(obj) is called (every time you equip/unequip some armor piece, take damage, and more)
|
||||||
|
--note that the enchanting overlay will not appear unless you implement it in the function
|
||||||
|
--this allow to make armors where the textures change whitout needing to register many other armors with different textures
|
||||||
|
textures = {
|
||||||
|
head = function(obj, itemstack)
|
||||||
|
if mcl_enchanting.is_enchanted(itemstack) then
|
||||||
|
return "dummy_texture.png^"..mcl_enchanting.overlay
|
||||||
|
else
|
||||||
|
return "dummy_texture.png"
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
--WARNING: 2d preview is deprecated and will be removed soon
|
||||||
|
--specify textures that will be shown in player inventory then you disabled the 3d player inventory preview
|
||||||
|
--its similar to how works the textures field
|
||||||
|
previews = {
|
||||||
|
head = "dummy_texture.png", --default: "<modname>_helmet_<material>_preview.png"
|
||||||
|
torso = "dummy_texture.png", --default: "<modname>_chestplate_<material>_preview.png"
|
||||||
|
legs = "dummy_texture.png", --default: "<modname>_leggings_<material>_preview.png"
|
||||||
|
feet = "dummy_texture.png", --default: "<modname>_boots_<material>_preview.png"
|
||||||
|
},
|
||||||
|
|
||||||
|
--inventory textures aren't definable using a table similar to textures or previews
|
||||||
|
--you are forced to use the default texture names which are:
|
||||||
|
--head: "<modname>_inv_helmet_<material>.png
|
||||||
|
--torso: "<modname>_inv_chestplate_<material>.png
|
||||||
|
--legs: "<modname>_inv_leggings_<material>.png
|
||||||
|
--feet: "<modname>_inv_boots_<material>.png
|
||||||
|
|
||||||
|
--this callback table allow you to define functions that will be called each time an entity equip an armor piece or the mcl_armor.on_equip() function is called
|
||||||
|
--the functions accept two arguments: obj and itemstack
|
||||||
|
on_equip_callbacks = {
|
||||||
|
head = function(obj, itemstack)
|
||||||
|
--do stuff
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
--this callback table allow you to define functions that will be called each time an entity unequip an armor piece or the mcl_armor.on_unequip() function is called
|
||||||
|
--the functions accept two arguments: obj and itemstack
|
||||||
|
on_unequip_callbacks = {
|
||||||
|
head = function(obj, itemstack)
|
||||||
|
--do stuff
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
--this callback table allow you to define functions that will be called then an armor piece break
|
||||||
|
--the functions accept one arguments: obj
|
||||||
|
--the itemstack isn't sended due to how minetest handle items which have a zero durability
|
||||||
|
on_break_callbacks = {
|
||||||
|
head = function(obj)
|
||||||
|
--do stuff
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
--this is used to generate automaticaly armor crafts based on each element type folowing the regular minecraft pattern
|
||||||
|
--if set to nil no craft will be added
|
||||||
|
craft_material = "mcl_mobitems:leather",
|
||||||
|
|
||||||
|
--this is used to generate cooking crafts for each piece of armor
|
||||||
|
--if set to nil no craft will be added
|
||||||
|
cook_material = "mcl_core:gold_nugget", --cooking any piece of this armor will output a gold nugged
|
||||||
|
|
||||||
|
--this is used for allowing each piece of the armor to be repaired by using an anvil with repair_material as aditionnal material
|
||||||
|
--it basicaly set the _repair_material item field of each piece of the armor
|
||||||
|
--if set to nil no repair material will be added
|
||||||
|
repair_material = "mcl_core:iron_ingot",
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creating an Armor Piece
|
||||||
|
|
||||||
|
If you don't want to register a full set of armor, then you will need to manually register your own single item.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
minetest.register_tool("dummy_mod:random_armor", {
|
||||||
|
description = S("Random Armor"),
|
||||||
|
|
||||||
|
--these two item fields are used for ingame documentation
|
||||||
|
--the mcl_armor.longdesc and mcl_armor.usage vars contains the basic usage and purpose of a piece of armor
|
||||||
|
--these vars may not be enough for that you want to do, so you may add some extra informations like that:
|
||||||
|
--_doc_items_longdesc = mcl_armor.longdesc.." "..S("Some extra informations.")
|
||||||
|
_doc_items_longdesc = mcl_armor.longdesc,
|
||||||
|
_doc_items_usagehelp = mcl_armor.usage,
|
||||||
|
|
||||||
|
--this field is similar to any item definition in minetest
|
||||||
|
--it just set the image shown then the armor is dropped as an item or inside an inventory
|
||||||
|
inventory_image = "mcl_armor_inv_elytra.png",
|
||||||
|
|
||||||
|
--this field is used by minetest internally and also by some helper functions
|
||||||
|
--in order for the tool to be shown is the right creative inventory tab, the right groups should be added
|
||||||
|
--"mcl_armor_uses" is required to give your armor a durability
|
||||||
|
--in that case, the armor can be worn by 10 points before breaking
|
||||||
|
--if you want the armor to be enchantable, you should also add the "enchantability" group, with the highest number the better enchants you can apply
|
||||||
|
groups = {armor = 1, non_combat_armor = 1, armor_torso = 1, non_combat_torso = 1, mcl_armor_uses = 10},
|
||||||
|
|
||||||
|
--this table is used by minetest for seraching item specific sounds
|
||||||
|
--the _mcl_armor_equip and _mcl_armor_unequip are used by the armor implementation to play sounds on equip and unequip
|
||||||
|
--note that you don't need to provide any file extention
|
||||||
|
sounds = {
|
||||||
|
_mcl_armor_equip = "mcl_armor_equip_leather",
|
||||||
|
_mcl_armor_unequip = "mcl_armor_unequip_leather",
|
||||||
|
},
|
||||||
|
|
||||||
|
--these fields should be initialised like that in most cases
|
||||||
|
--mcl_armor.equip_on_use is a function that try to equip the piece of armor you have in hand inside the right armor slot if the slot is empty
|
||||||
|
on_place = mcl_armor.equip_on_use,
|
||||||
|
on_secondary_use = mcl_armor.equip_on_use,
|
||||||
|
|
||||||
|
--this field define that the tool is ACTUALLY an armor piece and in which armor slot you can put it
|
||||||
|
--it should be set to "head", "torso", "legs" or "feet"
|
||||||
|
_mcl_armor_element = "torso",
|
||||||
|
|
||||||
|
|
||||||
|
--this field is used to provide the texture that will be overlayed on the object (player or mob) skin
|
||||||
|
--this field can be a texture name or a function that will be called each time the mcl_armor.update(obj) function is called
|
||||||
|
--see the mcl_armor.register_set() documentation for more explanations
|
||||||
|
_mcl_armor_texture = "mcl_armor_elytra.png"
|
||||||
|
|
||||||
|
--callbacks
|
||||||
|
--see the mcl_armor.register_set() documentation for more explanations
|
||||||
|
|
||||||
|
_on_equip = function(obj, itemstack)
|
||||||
|
end,
|
||||||
|
_on_unequip = function(obj, itemstack)
|
||||||
|
end,
|
||||||
|
_on_break = function(obj)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interacting with Armor of an Entity
|
||||||
|
|
||||||
|
Mods may want to interact with armor of an entity.
|
||||||
|
|
||||||
|
Most global functions not described here may not be stable or may be for internal use only.
|
||||||
|
|
||||||
|
You can equip a piece of armor on an entity inside a mod by using `mcl_armor.equip()`.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
--itemstack: an itemstack containing the armor piece to equip
|
||||||
|
--obj: the entity you want to equip the armor on
|
||||||
|
--swap: boolean, force equiping the armor piece, even if the entity already have one of the same type
|
||||||
|
mcl_armor.equip(itemstack, obj, swap)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can update the entity apparence by using `mcl_armor.update()`.
|
||||||
|
|
||||||
|
This function put the armor overlay on the object's base texture.
|
||||||
|
If the object is player it will update his displayed armor points count in HUD.
|
||||||
|
|
||||||
|
This function will work both on players and mobs.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
--obj: the entity you want the apparence to be updated
|
||||||
|
mcl_armor.update(obj)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Handling Enchantments
|
||||||
|
|
||||||
|
Armors can be enchanted in most cases.
|
||||||
|
|
||||||
|
The enchanting part of MineClone2 is separated from the armor part, but closely linked.
|
||||||
|
|
||||||
|
Existing armor enchantments in Minecraft improve most of the time how the armor protect the entity from damage.
|
||||||
|
|
||||||
|
The `mcl_armor.register_protection_enchantment()` function aims to simplificate the creation of such enchants.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
mcl_armor.register_protection_enchantment({
|
||||||
|
--this field is the id that will be used for registering enchanted book and store the enchant inside armor metadata.
|
||||||
|
--(his internal name)
|
||||||
|
id = "magic_protection",
|
||||||
|
|
||||||
|
--visible name of the enchant
|
||||||
|
--this field is used as the name of registered enchanted book and inside armor tooltip
|
||||||
|
--translation should be added
|
||||||
|
name = S("Magic Protection"),
|
||||||
|
|
||||||
|
--this field is used to know that the enchant currently do
|
||||||
|
--translation should be added
|
||||||
|
description = S("Reduces magic damage."),
|
||||||
|
|
||||||
|
--how many levels can the enchant have
|
||||||
|
--ex: 4 => I, II, III, IV
|
||||||
|
--default: 4
|
||||||
|
max_level = 4,
|
||||||
|
|
||||||
|
--which enchants this enchant will not be compatible with
|
||||||
|
--each of these values is a enchant id
|
||||||
|
incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true},
|
||||||
|
|
||||||
|
--how much will the enchant consume from the enchantability group of the armor item
|
||||||
|
--default: 5
|
||||||
|
weight = 5,
|
||||||
|
|
||||||
|
--false => the enchant can be obtained in an enchanting table
|
||||||
|
--true => the enchant isn't obtainable in the enchanting table
|
||||||
|
--is true, you will probably need to implement some ways to obtain it
|
||||||
|
--even it the field is named "treasure", it will be no way to find it
|
||||||
|
--default: false
|
||||||
|
treasure = false,
|
||||||
|
|
||||||
|
--how much will damage be reduced
|
||||||
|
--see Minecraft Wiki for more informations
|
||||||
|
--https://minecraft.gamepedia.com/Armor#Damage_protection
|
||||||
|
--https://minecraft.gamepedia.com/Armor#Enchantments
|
||||||
|
factor = 1,
|
||||||
|
|
||||||
|
--restrict damage to one type
|
||||||
|
--allow the enchant to only protect of one type of damage
|
||||||
|
damage_type = "magic",
|
||||||
|
|
||||||
|
--restrict damage to one category
|
||||||
|
--allow to protect from many type of damage at once
|
||||||
|
--this is much less specific than damage_type and also much more customisable
|
||||||
|
--the "is_magic" flag is used in the "magic", "dragon_breath", "wither_skull" and "thorns" damage types
|
||||||
|
--you can checkout the mcl_damage source code for a list of availlable damage types and associated flags
|
||||||
|
--but be warned that mods can register additionnal damage types
|
||||||
|
damage_flag = "is_magic",
|
||||||
|
})
|
||||||
|
```
|
|
@ -33,8 +33,10 @@ if mod_mcl_core then
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_buckets = {}
|
mcl_buckets = {
|
||||||
mcl_buckets.liquids = {}
|
liquids = {},
|
||||||
|
buckets = {},
|
||||||
|
}
|
||||||
|
|
||||||
-- Sound helper functions for placing and taking liquids
|
-- Sound helper functions for placing and taking liquids
|
||||||
local function sound_place(itemname, pos)
|
local function sound_place(itemname, pos)
|
||||||
|
@ -147,6 +149,172 @@ local function get_bucket_drop(itemstack, user, take_bucket)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function on_place_bucket(itemstack, user, pointed_thing, def)
|
||||||
|
-- Must be pointing to node
|
||||||
|
if pointed_thing.type ~= "node" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- Call on_rightclick if the pointed node defines it
|
||||||
|
local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing)
|
||||||
|
if new_stack then
|
||||||
|
return new_stack
|
||||||
|
end
|
||||||
|
|
||||||
|
local undernode = get_node(pointed_thing.under)
|
||||||
|
local abovenode = get_node(pointed_thing.above)
|
||||||
|
local buildable1 = minetest.registered_nodes[undernode.name] and minetest.registered_nodes[undernode.name].buildable_to
|
||||||
|
local buildable2 = minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to
|
||||||
|
if not buildable1 and not buildable2 then return itemstack end --if both nodes aren't buildable_to, skip
|
||||||
|
|
||||||
|
if buildable1 then
|
||||||
|
local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.under, user)
|
||||||
|
if result then
|
||||||
|
local node_place = get_node_place(def.source_place, pointed_thing.under)
|
||||||
|
local pns = user:get_player_name()
|
||||||
|
|
||||||
|
-- Check protection
|
||||||
|
if minetest.is_protected(pointed_thing.under, pns) then
|
||||||
|
minetest.record_protection_violation(pointed_thing.under, pns)
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Place liquid
|
||||||
|
place_liquid(pointed_thing.under, node_place)
|
||||||
|
|
||||||
|
-- Update doc mod
|
||||||
|
if mod_doc and doc.entry_exists("nodes", node_place) then
|
||||||
|
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return get_bucket_drop(itemstack, user, take_bucket)
|
||||||
|
elseif buildable2 then
|
||||||
|
local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.above, user)
|
||||||
|
if result then
|
||||||
|
local node_place = get_node_place(def.source_place, pointed_thing.above)
|
||||||
|
local pns = user:get_player_name()
|
||||||
|
|
||||||
|
-- Check protection
|
||||||
|
if minetest.is_protected(pointed_thing.above, pns) then
|
||||||
|
minetest.record_protection_violation(pointed_thing.above, pns)
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Place liquid
|
||||||
|
place_liquid(pointed_thing.above, node_place)
|
||||||
|
|
||||||
|
-- Update doc mod
|
||||||
|
if mod_doc and doc.entry_exists("nodes", node_place) then
|
||||||
|
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return get_bucket_drop(itemstack, user, take_bucket)
|
||||||
|
else
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function on_place_bucket_empty(itemstack, user, pointed_thing)
|
||||||
|
-- Must be pointing to node
|
||||||
|
if pointed_thing.type ~= "node" then
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Call on_rightclick if the pointed node defines it
|
||||||
|
local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing)
|
||||||
|
if new_stack then
|
||||||
|
return new_stack
|
||||||
|
end
|
||||||
|
|
||||||
|
local node = minetest.get_node(pointed_thing.under)
|
||||||
|
local nn = node.name
|
||||||
|
|
||||||
|
local new_bucket
|
||||||
|
local liquid_node = bucket_raycast(user)
|
||||||
|
if liquid_node then
|
||||||
|
if minetest.is_protected(liquid_node.above, user:get_player_name()) then
|
||||||
|
minetest.record_protection_violation(liquid_node.above, user:get_player_name())
|
||||||
|
end
|
||||||
|
local liquid_name = get_node(liquid_node.above).name
|
||||||
|
if liquid_name then
|
||||||
|
local liquid_def = mcl_buckets.liquids[liquid_name]
|
||||||
|
if liquid_def then
|
||||||
|
--minetest.chat_send_all("test")
|
||||||
|
-- Fill bucket, but not in Creative Mode
|
||||||
|
-- FIXME: remove this line
|
||||||
|
--if not minetest.is_creative_enabled(user:get_player_name()) then
|
||||||
|
if not false then
|
||||||
|
new_bucket = ItemStack({name = liquid_def.bucketname})
|
||||||
|
if liquid_def.on_take then
|
||||||
|
liquid_def.on_take(user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
add_node(liquid_node.above, {name="air"})
|
||||||
|
sound_take(nn, liquid_node.above)
|
||||||
|
|
||||||
|
if mod_doc and doc.entry_exists("nodes", liquid_name) then
|
||||||
|
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", liquid_name)
|
||||||
|
end
|
||||||
|
if new_bucket then
|
||||||
|
return give_bucket(new_bucket, itemstack, user)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.log("error", string.format("[mcl_buckets] Node [%s] has invalid group [_mcl_bucket_pointable]!", liquid_name))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return itemstack
|
||||||
|
else
|
||||||
|
-- FIXME: replace this ugly code by cauldrons API
|
||||||
|
if nn == "mcl_cauldrons:cauldron_3" then
|
||||||
|
-- Take water out of full cauldron
|
||||||
|
minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"})
|
||||||
|
if not minetest.is_creative_enabled(user:get_player_name()) then
|
||||||
|
new_bucket = ItemStack("mcl_buckets:bucket_water")
|
||||||
|
end
|
||||||
|
sound_take("mcl_core:water_source", pointed_thing.under)
|
||||||
|
elseif nn == "mcl_cauldrons:cauldron_3r" then
|
||||||
|
-- Take river water out of full cauldron
|
||||||
|
minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"})
|
||||||
|
if not minetest.is_creative_enabled(user:get_player_name()) then
|
||||||
|
new_bucket = ItemStack("mcl_buckets:bucket_river_water")
|
||||||
|
end
|
||||||
|
sound_take("mclx_core:river_water_source", pointed_thing.under)
|
||||||
|
end
|
||||||
|
if new_bucket then
|
||||||
|
return give_bucket(new_bucket, itemstack, user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
controls.register_on_press(function(player, key)
|
||||||
|
if key ~= "RMB" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local wielded_item = player:get_wielded_item()
|
||||||
|
local itemname = wielded_item:get_name()
|
||||||
|
local def = mcl_buckets.buckets[itemname]
|
||||||
|
|
||||||
|
if itemname == "mcl_buckets:bucket_empty" then
|
||||||
|
local pointed_thing = mcl_util.get_pointed_thing(player, true)
|
||||||
|
|
||||||
|
if not pointed_thing then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
wielded_item = on_place_bucket_empty(wielded_item, player, pointed_thing)
|
||||||
|
elseif def then
|
||||||
|
local pointed_thing = mcl_util.get_pointed_thing(player, false)
|
||||||
|
|
||||||
|
if not pointed_thing then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
wielded_item = on_place_bucket(wielded_item, player, pointed_thing, def)
|
||||||
|
end
|
||||||
|
|
||||||
|
player:set_wielded_item(wielded_item)
|
||||||
|
end)
|
||||||
|
|
||||||
function mcl_buckets.register_liquid(def)
|
function mcl_buckets.register_liquid(def)
|
||||||
for _,source in ipairs(def.source_take) do
|
for _,source in ipairs(def.source_take) do
|
||||||
mcl_buckets.liquids[source] = {
|
mcl_buckets.liquids[source] = {
|
||||||
|
@ -161,6 +329,8 @@ function mcl_buckets.register_liquid(def)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
mcl_buckets.buckets[def.bucketname] = def
|
||||||
|
|
||||||
if def.bucketname == nil or def.bucketname == "" then
|
if def.bucketname == nil or def.bucketname == "" then
|
||||||
error(string.format("[mcl_bucket] Invalid itemname then registering [%s]!", def.name))
|
error(string.format("[mcl_bucket] Invalid itemname then registering [%s]!", def.name))
|
||||||
end
|
end
|
||||||
|
@ -173,69 +343,6 @@ function mcl_buckets.register_liquid(def)
|
||||||
inventory_image = def.inventory_image,
|
inventory_image = def.inventory_image,
|
||||||
stack_max = 1,
|
stack_max = 1,
|
||||||
groups = def.groups,
|
groups = def.groups,
|
||||||
on_place = function(itemstack, user, pointed_thing)
|
|
||||||
-- Must be pointing to node
|
|
||||||
if pointed_thing.type ~= "node" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- Call on_rightclick if the pointed node defines it
|
|
||||||
local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing)
|
|
||||||
if new_stack then
|
|
||||||
return new_stack
|
|
||||||
end
|
|
||||||
|
|
||||||
local undernode = get_node(pointed_thing.under)
|
|
||||||
local abovenode = get_node(pointed_thing.above)
|
|
||||||
local buildable1 = minetest.registered_nodes[undernode.name] and minetest.registered_nodes[undernode.name].buildable_to
|
|
||||||
local buildable2 = minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to
|
|
||||||
if not buildable1 and not buildable2 then return itemstack end --if both nodes aren't buildable_to, skip
|
|
||||||
|
|
||||||
if buildable1 then
|
|
||||||
local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.under, user)
|
|
||||||
if result then
|
|
||||||
local node_place = get_node_place(def.source_place, pointed_thing.under)
|
|
||||||
local pns = user:get_player_name()
|
|
||||||
|
|
||||||
-- Check protection
|
|
||||||
if minetest.is_protected(pointed_thing.under, pns) then
|
|
||||||
minetest.record_protection_violation(pointed_thing.under, pns)
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Place liquid
|
|
||||||
place_liquid(pointed_thing.under, node_place)
|
|
||||||
|
|
||||||
-- Update doc mod
|
|
||||||
if mod_doc and doc.entry_exists("nodes", node_place) then
|
|
||||||
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return get_bucket_drop(itemstack, user, take_bucket)
|
|
||||||
elseif buildable2 then
|
|
||||||
local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.above, user)
|
|
||||||
if result then
|
|
||||||
local node_place = get_node_place(def.source_place, pointed_thing.above)
|
|
||||||
local pns = user:get_player_name()
|
|
||||||
|
|
||||||
-- Check protection
|
|
||||||
if minetest.is_protected(pointed_thing.above, pns) then
|
|
||||||
minetest.record_protection_violation(pointed_thing.above, pns)
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Place liquid
|
|
||||||
place_liquid(pointed_thing.above, node_place)
|
|
||||||
|
|
||||||
-- Update doc mod
|
|
||||||
if mod_doc and doc.entry_exists("nodes", node_place) then
|
|
||||||
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return get_bucket_drop(itemstack, user, take_bucket)
|
|
||||||
else
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
||||||
local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal"
|
local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal"
|
||||||
if not buildable then return stack end
|
if not buildable then return stack end
|
||||||
|
@ -259,78 +366,6 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", {
|
||||||
--liquids_pointable = true,
|
--liquids_pointable = true,
|
||||||
inventory_image = "bucket.png",
|
inventory_image = "bucket.png",
|
||||||
stack_max = 16,
|
stack_max = 16,
|
||||||
on_place = function(itemstack, user, pointed_thing)
|
|
||||||
-- Must be pointing to node
|
|
||||||
if pointed_thing.type ~= "node" then
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Call on_rightclick if the pointed node defines it
|
|
||||||
local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing)
|
|
||||||
if new_stack then
|
|
||||||
return new_stack
|
|
||||||
end
|
|
||||||
|
|
||||||
local node = minetest.get_node(pointed_thing.under)
|
|
||||||
local nn = node.name
|
|
||||||
|
|
||||||
local new_bucket
|
|
||||||
local liquid_node = bucket_raycast(user)
|
|
||||||
if liquid_node then
|
|
||||||
if minetest.is_protected(liquid_node.above, user:get_player_name()) then
|
|
||||||
minetest.record_protection_violation(liquid_node.above, user:get_player_name())
|
|
||||||
end
|
|
||||||
local liquid_name = get_node(liquid_node.above).name
|
|
||||||
if liquid_name then
|
|
||||||
local liquid_def = mcl_buckets.liquids[liquid_name]
|
|
||||||
if liquid_def then
|
|
||||||
--minetest.chat_send_all("test")
|
|
||||||
-- Fill bucket, but not in Creative Mode
|
|
||||||
-- FIXME: remove this line
|
|
||||||
--if not minetest.is_creative_enabled(user:get_player_name()) then
|
|
||||||
if not false then
|
|
||||||
new_bucket = ItemStack({name = liquid_def.bucketname})
|
|
||||||
if liquid_def.on_take then
|
|
||||||
liquid_def.on_take(user)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
add_node(liquid_node.above, {name="air"})
|
|
||||||
sound_take(nn, liquid_node.above)
|
|
||||||
|
|
||||||
if mod_doc and doc.entry_exists("nodes", liquid_name) then
|
|
||||||
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", liquid_name)
|
|
||||||
end
|
|
||||||
if new_bucket then
|
|
||||||
return give_bucket(new_bucket, itemstack, user)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
minetest.log("error", string.format("[mcl_buckets] Node [%s] has invalid group [_mcl_bucket_pointable]!", liquid_name))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return itemstack
|
|
||||||
else
|
|
||||||
-- FIXME: replace this ugly code by cauldrons API
|
|
||||||
if nn == "mcl_cauldrons:cauldron_3" then
|
|
||||||
-- Take water out of full cauldron
|
|
||||||
minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"})
|
|
||||||
if not minetest.is_creative_enabled(user:get_player_name()) then
|
|
||||||
new_bucket = ItemStack("mcl_buckets:bucket_water")
|
|
||||||
end
|
|
||||||
sound_take("mcl_core:water_source", pointed_thing.under)
|
|
||||||
elseif nn == "mcl_cauldrons:cauldron_3r" then
|
|
||||||
-- Take river water out of full cauldron
|
|
||||||
minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"})
|
|
||||||
if not minetest.is_creative_enabled(user:get_player_name()) then
|
|
||||||
new_bucket = ItemStack("mcl_buckets:bucket_river_water")
|
|
||||||
end
|
|
||||||
sound_take("mclx_core:river_water_source", pointed_thing.under)
|
|
||||||
end
|
|
||||||
if new_bucket then
|
|
||||||
return give_bucket(new_bucket, itemstack, user)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return itemstack
|
|
||||||
end,
|
|
||||||
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
||||||
-- Fill empty bucket with liquid or drop bucket if no liquid
|
-- Fill empty bucket with liquid or drop bucket if no liquid
|
||||||
local collect_liquid = false
|
local collect_liquid = false
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name = mcl_buckets
|
name = mcl_buckets
|
||||||
author = Kahrl
|
author = Kahrl
|
||||||
description =
|
description =
|
||||||
depends = mcl_worlds, mcl_util
|
depends = mcl_worlds, mcl_util, controls
|
||||||
optional_depends = mcl_core, mclx_core, doc
|
optional_depends = mcl_core, mclx_core, doc
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue