Merge remote-tracking branch 'origin/master' into testing

This commit is contained in:
kay27 2022-07-05 15:02:23 +03:00
commit 98855596f9
43 changed files with 356 additions and 107 deletions

View File

@ -156,6 +156,10 @@ minetest.register_globalstep(function(dtime)
object:set_velocity({x=0,y=0,z=0}) object:set_velocity({x=0,y=0,z=0})
object:set_acceleration({x=0,y=0,z=0}) object:set_acceleration({x=0,y=0,z=0})
if object._flowing then
object._flowing = false
end
object:move_to(checkpos) object:move_to(checkpos)
pool[name] = pool[name] + 1 pool[name] = pool[name] + 1
@ -795,6 +799,9 @@ minetest.register_entity(":__builtin:item", {
local oldvel = self.object:get_velocity() -- v is vector, vel is velocity local oldvel = self.object:get_velocity() -- v is vector, vel is velocity
-- apply gravity *before* drag computations
oldvel.y = oldvel.y - get_gravity() * dtime
-- drag -- drag
local fluid_drag = item_drop_settings.fluid_drag local fluid_drag = item_drop_settings.fluid_drag
@ -809,12 +816,6 @@ minetest.register_entity(":__builtin:item", {
newv.y = newv.y - (oldvel.y - newv.y) * fluid_drag * dtime newv.y = newv.y - (oldvel.y - newv.y) * fluid_drag * dtime
newv.z = newv.z - (oldvel.z - newv.z) * fluid_drag * dtime newv.z = newv.z - (oldvel.z - newv.z) * fluid_drag * dtime
newv.y = newv.y + -0.22 -- (keep slight downward thrust from previous version of code)
-- NOTE: is there any particular reason we have this, anyway?
-- since fluid drag is now on, we could as well just
-- apply gravity here; drag will slow down the fall
-- realistically
self.object:set_velocity({x = oldvel.x + newv.x * dtime, y = oldvel.y + newv.y * dtime, z = oldvel.z + newv.z * dtime}) self.object:set_velocity({x = oldvel.x + newv.x * dtime, y = oldvel.y + newv.y * dtime, z = oldvel.z + newv.z * dtime})
self.physical_state = true self.physical_state = true

View File

@ -26,6 +26,8 @@ local math_random = math.random
|_| |_|
]]-- ]]--
local minetest_line_of_sight = minetest.line_of_sight
mobs.explode_attack_walk = function(self,dtime) mobs.explode_attack_walk = function(self,dtime)
--this needs an exception --this needs an exception
@ -36,17 +38,27 @@ mobs.explode_attack_walk = function(self,dtime)
mobs.set_yaw_while_attacking(self) mobs.set_yaw_while_attacking(self)
local distance_from_attacking = vector_distance(self.object:get_pos(), self.attacking:get_pos()) local pos = self.object:get_pos()
local attack_pos = self.attacking:get_pos()
local distance_from_attacking = vector_distance(pos, attack_pos)
--make mob walk up to player within 2 nodes distance then start exploding --make mob walk up to player within 2 nodes distance then start exploding
if distance_from_attacking >= self.reach and if (
--don't allow explosion to cancel unless out of the reach boundary distance_from_attacking >= self.reach and
not (self.explosion_animation and self.explosion_animation > 0 and distance_from_attacking <= self.defuse_reach) then
--don't allow explosion to cancel unless out of the reach boundary
not (self.explosion_animation and self.explosion_animation > 0 and distance_from_attacking <= self.defuse_reach) or
--don't allow creeper to finish exploding animation if can't see target
not minetest_line_of_sight(
{x = pos.x, y = pos.y + self.eye_height, z = pos.z},
{x = attack_pos.x, y = attack_pos.y + (self.attacking.eye_height or 0), z = attack_pos.z}
)
) then
mobs.set_velocity(self, self.run_velocity) mobs.set_velocity(self, self.run_velocity)
mobs.set_mob_animation(self,"run") mobs.set_mob_animation(self,"run")
mobs.reverse_explosion_animation(self,dtime) mobs.reverse_explosion_animation(self,dtime)
else else
mobs.set_velocity(self,0) mobs.set_velocity(self,0)

View File

@ -339,14 +339,6 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size,
if name == "inv" then if name == "inv" then
inv_bg = "crafting_inventory_creative_survival.png" inv_bg = "crafting_inventory_creative_survival.png"
-- Show armor and player image
local player_preview
if minetest.settings:get_bool("3d_player_preview", true) then
player_preview = mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "")
else
player_preview = "image[3.9,1.4;1.2333,2.4666;"..mcl_player.player_get_preview(player).."]"
end
-- Background images for armor slots (hide if occupied) -- Background images for armor slots (hide if occupied)
local armor_slot_imgs = "" local armor_slot_imgs = ""
local inv = player:get_inventory() local inv = player:get_inventory()
@ -386,8 +378,7 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size,
armor_slot_imgs.. armor_slot_imgs..
-- player preview -- player preview
player_preview.. mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "")..
-- crafting guide button -- crafting guide button
"image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]".. "image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]"..
"tooltip[__mcl_craftguide;"..F(S("Recipe book")).."]".. "tooltip[__mcl_craftguide;"..F(S("Recipe book")).."]"..

View File

@ -61,14 +61,6 @@ local function set_inventory(player, armor_change_only)
inv:set_width("craft", 2) inv:set_width("craft", 2)
inv:set_size("craft", 4) inv:set_size("craft", 4)
-- Show armor and player image
local player_preview
if minetest.settings:get_bool("3d_player_preview", true) then
player_preview = mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "")
else
player_preview = "image[1.1,0.2;2,4;"..mcl_player.player_get_preview(player).."]"
end
local armor_slots = {"helmet", "chestplate", "leggings", "boots"} local armor_slots = {"helmet", "chestplate", "leggings", "boots"}
local armor_slot_imgs = "" local armor_slot_imgs = ""
for a=1,4 do for a=1,4 do
@ -83,7 +75,7 @@ local function set_inventory(player, armor_change_only)
local form = "size[9,8.75]".. local form = "size[9,8.75]"..
"background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]".. "background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]"..
player_preview.. mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "")..
--armor --armor
"list[current_player;armor;0,0;1,1;1]".. "list[current_player;armor;0,0;1,1;1]"..
"list[current_player;armor;0,1;1,1;2]".. "list[current_player;armor;0,1;1,1;2]"..

288
mods/ITEMS/mcl_armor/API.md Normal file
View File

@ -0,0 +1,288 @@
# 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,
},
--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",
})
```

View File

@ -94,7 +94,6 @@ function mcl_armor.register_set(def)
local on_unequip_callbacks = def.on_unequip_callbacks or {} local on_unequip_callbacks = def.on_unequip_callbacks or {}
local on_break_callbacks = def.on_break_callbacks or {} local on_break_callbacks = def.on_break_callbacks or {}
local textures = def.textures or {} local textures = def.textures or {}
local previews = def.previews or {}
local durabilities = def.durabilities or {} local durabilities = def.durabilities or {}
local element_groups = def.element_groups or {} local element_groups = def.element_groups or {}
@ -134,8 +133,7 @@ function mcl_armor.register_set(def)
_on_break = on_break_callbacks[name] or def.on_break, _on_break = on_break_callbacks[name] or def.on_break,
_mcl_armor_element = name, _mcl_armor_element = name,
_mcl_armor_texture = textures[name] or modname .. "_" .. itemname .. ".png", _mcl_armor_texture = textures[name] or modname .. "_" .. itemname .. ".png",
_mcl_armor_preview = previews[name] or modname .. "_" .. itemname .. "_preview.png", _mcl_upgradable = def.upgradable
_mcl_upgradable = def.upgradable,
}) })
if def.craft_material then if def.craft_material then
@ -222,17 +220,6 @@ function mcl_armor.update(obj)
end end
end end
local preview = def._mcl_armor_preview
if obj:is_player() and preview then
if type(preview) == "function" then
preview = preview(obj, itemstack)
end
if preview then
info.preview = "(player.png^[opacity:0^" .. def._mcl_armor_preview .. ")" .. (info.preview and "^" .. info.preview or "" )
end
end
info.points = info.points + minetest.get_item_group(itemname, "mcl_armor_points") info.points = info.points + minetest.get_item_group(itemname, "mcl_armor_points")
local mob_range_mob = def._mcl_armor_mob_range_mob local mob_range_mob = def._mcl_armor_mob_range_mob
@ -255,8 +242,6 @@ function mcl_armor.update(obj)
info.texture = info.texture or "blank.png" info.texture = info.texture or "blank.png"
if obj:is_player() then if obj:is_player() then
info.preview = info.preview or "blank.png"
mcl_armor.update_player(obj, info) mcl_armor.update_player(obj, info)
else else
local luaentity = obj:get_luaentity() local luaentity = obj:get_luaentity()

View File

@ -63,7 +63,7 @@ mcl_player.player_register_model("mcl_armor_character_female.b3d", {
}) })
function mcl_armor.update_player(player, info) function mcl_armor.update_player(player, info)
mcl_player.player_set_armor(player, info.texture, info.preview) mcl_player.player_set_armor(player, info.texture)
local meta = player:get_meta() local meta = player:get_meta()
meta:set_int("mcl_armor:armor_points", info.points) meta:set_int("mcl_armor:armor_points", info.points)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 B

View File

@ -271,11 +271,10 @@ function mcl_enchanting.initialize()
new_def.groups.not_in_craft_guide = 1 new_def.groups.not_in_craft_guide = 1
new_def.groups.enchanted = 1 new_def.groups.enchanted = 1
if new_def._mcl_armor_texture and not type(new_def._mcl_armor_texture) == "function" then if new_def._mcl_armor_texture then
if type(new_def._mcl_armor_texture) == "string" then
new_def._mcl_armor_texture = new_def._mcl_armor_texture .. mcl_enchanting.overlay new_def._mcl_armor_texture = new_def._mcl_armor_texture .. mcl_enchanting.overlay
end end
if new_def._mcl_armor_preview and not type(new_def._mcl_armor_preview) == "function" then
new_def._mcl_armor_preview = new_def._mcl_armor_preview .. mcl_enchanting.overlay
end end
new_def._mcl_enchanting_enchanted_tool = new_name new_def._mcl_enchanting_enchanted_tool = new_name

View File

@ -120,7 +120,6 @@ pumpkin_face_base_def._mcl_armor_mob_range_factor = 0
pumpkin_face_base_def._mcl_armor_mob_range_mob = "mobs_mc:enderman" pumpkin_face_base_def._mcl_armor_mob_range_mob = "mobs_mc:enderman"
pumpkin_face_base_def._mcl_armor_element = "head" pumpkin_face_base_def._mcl_armor_element = "head"
pumpkin_face_base_def._mcl_armor_texture = "mcl_farming_pumpkin_face.png" pumpkin_face_base_def._mcl_armor_texture = "mcl_farming_pumpkin_face.png"
pumpkin_face_base_def._mcl_armor_preview = "mcl_farming_pumpkin_face_preview.png"
if minetest.get_modpath("mcl_armor") then if minetest.get_modpath("mcl_armor") then
local pumpkin_hud = {} local pumpkin_hud = {}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 B

View File

@ -113,7 +113,6 @@ local function addhead(name, texture, desc, longdesc, rangemob, rangefactor)
_mcl_armor_mob_range_factor = rangefactor, _mcl_armor_mob_range_factor = rangefactor,
_mcl_armor_element = "head", _mcl_armor_element = "head",
_mcl_armor_texture = "mcl_heads_" .. name .. ".png", _mcl_armor_texture = "mcl_heads_" .. name .. ".png",
_mcl_armor_preview = "mcl_heads_" .. name .. "_preview.png",
_mcl_blast_resistance = 1, _mcl_blast_resistance = 1,
_mcl_hardness = 1, _mcl_hardness = 1,
}) })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

View File

@ -1,5 +1,7 @@
local S = minetest.get_translator(minetest.get_current_modname()) local S = minetest.get_translator(minetest.get_current_modname())
local get_item_group = minetest.get_item_group
--[[ BEGIN OF NODE DEFINITIONS ]] --[[ BEGIN OF NODE DEFINITIONS ]]
local mcl_hoppers_formspec = local mcl_hoppers_formspec =
@ -343,14 +345,15 @@ minetest.register_abm({
local abovenode = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}) local abovenode = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z})
if not minetest.registered_items[abovenode.name] then return end if not minetest.registered_items[abovenode.name] then return end
-- Don't bother checking item enties if node above is a container (should save some CPU) -- Don't bother checking item enties if node above is a container (should save some CPU)
if minetest.registered_items[abovenode.name].groups.container then if get_item_group(abovenode.name, "container") then
return return
end end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local inv = meta:get_inventory() local inv = meta:get_inventory()
for _,object in pairs(minetest.get_objects_inside_radius(pos, 2)) do for _,object in pairs(minetest.get_objects_inside_radius(pos, 2)) do
if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and not object:get_luaentity()._removed then local entity = object:get_luaentity()
if not object:is_player() and entity and entity.name == "__builtin:item" and not entity._removed then
if inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then if inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
-- Item must get sucked in when the item just TOUCHES the block above the hopper -- Item must get sucked in when the item just TOUCHES the block above the hopper
-- This is the reason for the Y calculation. -- This is the reason for the Y calculation.
@ -358,9 +361,10 @@ minetest.register_abm({
local posob = object:get_pos() local posob = object:get_pos()
local posob_miny = posob.y + object:get_properties().collisionbox[2] local posob_miny = posob.y + object:get_properties().collisionbox[2]
if math.abs(posob.x-pos.x) <= 0.5 and (posob_miny-pos.y < 1.5 and posob.y-pos.y >= 0.3) then if math.abs(posob.x-pos.x) <= 0.5 and (posob_miny-pos.y < 1.5 and posob.y-pos.y >= 0.3) then
inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) entity._removed = true
object:get_luaentity().itemstring = "" entity.itemstring = ""
object:remove() object:remove()
inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
end end
end end
end end
@ -397,7 +401,7 @@ minetest.register_abm({
-- Suck an item from the container above into the hopper -- Suck an item from the container above into the hopper
local upnode = minetest.get_node(uppos) local upnode = minetest.get_node(uppos)
if not minetest.registered_nodes[upnode.name] then return end if not minetest.registered_nodes[upnode.name] then return end
local g = minetest.registered_nodes[upnode.name].groups.container local g = get_item_group(upnode.name, "container")
local sucked = mcl_util.move_item_container(uppos, pos) local sucked = mcl_util.move_item_container(uppos, pos)
-- Also suck in non-fuel items from furnace fuel slot -- Also suck in non-fuel items from furnace fuel slot
@ -435,6 +439,7 @@ minetest.register_abm({
front = {x=pos.x,y=pos.y,z=pos.z-1} front = {x=pos.x,y=pos.y,z=pos.z-1}
end end
local above = {x=pos.x,y=pos.y+1,z=pos.z} local above = {x=pos.x,y=pos.y+1,z=pos.z}
local downpos = {x=pos.x,y=pos.y-1,z=pos.z}
local frontnode = minetest.get_node(front) local frontnode = minetest.get_node(front)
if not minetest.registered_nodes[frontnode.name] then return end if not minetest.registered_nodes[frontnode.name] then return end
@ -442,7 +447,7 @@ minetest.register_abm({
-- Suck an item from the container above into the hopper -- Suck an item from the container above into the hopper
local abovenode = minetest.get_node(above) local abovenode = minetest.get_node(above)
if not minetest.registered_nodes[abovenode.name] then return end if not minetest.registered_nodes[abovenode.name] then return end
local g = minetest.registered_nodes[abovenode.name].groups.container local g = get_item_group(abovenode.name, "container")
local sucked = mcl_util.move_item_container(above, pos) local sucked = mcl_util.move_item_container(above, pos)
-- Also suck in non-fuel items from furnace fuel slot -- Also suck in non-fuel items from furnace fuel slot
@ -453,8 +458,14 @@ minetest.register_abm({
end end
end end
-- Try to move an item below before moving it sideways
local downnode = minetest.get_node(downpos)
if minetest.registered_nodes[downnode.name] and
mcl_util.move_item_container(pos, downpos) then return end
-- Move an item from the hopper into the container to which the hopper points to -- Move an item from the hopper into the container to which the hopper points to
local g = minetest.registered_nodes[frontnode.name].groups.container local g = get_item_group(frontnode.name, "container")
if g == 2 or g == 3 or g == 5 or g == 6 then if g == 2 or g == 3 or g == 5 or g == 6 then
mcl_util.move_item_container(pos, front) mcl_util.move_item_container(pos, front)
elseif g == 4 then elseif g == 4 then

View File

@ -95,31 +95,16 @@ local function set_texture(player, index, texture)
player:set_properties({textures = textures}) player:set_properties({textures = textures})
end end
local function set_preview(player, field, preview) function mcl_player.player_set_skin(player, texture)
player:get_meta():set_string("mcl_player:" .. field .. "_preview", preview)
end
function mcl_player.player_set_skin(player, texture, preview)
set_texture(player, 1, texture) set_texture(player, 1, texture)
set_preview(player, "skin", preview)
end end
function mcl_player.player_set_armor(player, texture, preview) function mcl_player.player_set_armor(player, texture)
set_texture(player, 2, texture) set_texture(player, 2, texture)
set_preview(player, "armor", preview)
end end
function mcl_player.player_get_preview(player) function mcl_player.player_set_wielditem(player, texture)
local preview = player:get_meta():get_string("mcl_player:skin_preview") set_texture(player, 3, texture)
if preview == "" then
preview = "player.png"
end
local armor_preview = player:get_meta():set_string("mcl_player:armor_preview")
if armor_preview ~= "" then
preview = preview .. "^" .. armor_preview
end
return preview
end end
function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname) function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname)

4
mods/PLAYER/mcl_skins/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
!textures/mcl_skins_character_1.png
textures/mcl_skins_character_*
!meta/mcl_skins_character_1.txt
meta/mcl_skins_character_*

View File

@ -3,7 +3,7 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
mcl_skins = { mcl_skins = {
skins = {}, list = {}, previews = {}, meta = {}, has_preview = {}, skins = {}, list = {}, meta = {},
modpath = minetest.get_modpath(modname), modpath = minetest.get_modpath(modname),
skin_count = 0, -- counter of _custom_ skins (all skins except character.png) skin_count = 0, -- counter of _custom_ skins (all skins except character.png)
} }
@ -18,10 +18,8 @@ while true do
if id == 0 then if id == 0 then
skin = "character" skin = "character"
mcl_skins.has_preview[id] = true
else else
skin = "mcl_skins_character_" .. id skin = "mcl_skins_character_" .. id
local preview = "mcl_skins_player_" .. id
-- Does skin file exist? -- Does skin file exist?
f = io.open(mcl_skins.modpath .. "/textures/" .. skin .. ".png") f = io.open(mcl_skins.modpath .. "/textures/" .. skin .. ".png")
@ -31,20 +29,12 @@ while true do
break break
end end
f:close() f:close()
-- Does skin preview file exist?
local file_preview = io.open(mcl_skins.modpath .. "/textures/" .. preview .. ".png")
if file_preview == nil then
minetest.log("warning", "[mcl_skins] Player skin #"..id.." does not have preview image (player_"..id..".png)")
mcl_skins.has_preview[id] = false
else
mcl_skins.has_preview[id] = true
file_preview:close()
end
end end
mcl_skins.list[id] = skin mcl_skins.list[id] = skin
local metafile
-- does metadata exist for that skin file ? -- does metadata exist for that skin file ?
if id == 0 then if id == 0 then
metafile = "mcl_skins_character.txt" metafile = "mcl_skins_character.txt"
@ -89,12 +79,11 @@ function mcl_skins.set_player_skin(player, skin_id)
return false return false
end end
local playername = player:get_player_name() local playername = player:get_player_name()
local skin, preview local skin
if skin_id == nil or type(skin_id) ~= "number" or skin_id < 0 or skin_id > mcl_skins.skin_count then if skin_id == nil or type(skin_id) ~= "number" or skin_id < 0 or skin_id > mcl_skins.skin_count then
return false return false
elseif skin_id == 0 then elseif skin_id == 0 then
skin = "character" skin = "character"
preview = "player"
mcl_player.player_set_model(player, "mcl_armor_character.b3d") mcl_player.player_set_model(player, "mcl_armor_character.b3d")
else else
skin = "mcl_skins_character_" .. tostring(skin_id) skin = "mcl_skins_character_" .. tostring(skin_id)
@ -104,16 +93,9 @@ function mcl_skins.set_player_skin(player, skin_id)
else else
mcl_player.player_set_model(player, "mcl_armor_character.b3d") mcl_player.player_set_model(player, "mcl_armor_character.b3d")
end end
if mcl_skins.has_preview[skin_id] then
preview = "mcl_skins_player_" .. tostring(skin_id)
else
-- Fallback preview image if preview image is missing
preview = "mcl_skins_player_dummy"
end
end end
--local skin_file = skin .. ".png" --local skin_file = skin .. ".png"
mcl_skins.skins[playername] = skin mcl_skins.skins[playername] = skin
mcl_skins.previews[playername] = preview
player:get_meta():set_string("mcl_skins:skin_id", tostring(skin_id)) player:get_meta():set_string("mcl_skins:skin_id", tostring(skin_id))
mcl_skins.update_player_skin(player) mcl_skins.update_player_skin(player)
if has_mcl_inventory then if has_mcl_inventory then
@ -131,7 +113,7 @@ function mcl_skins.update_player_skin(player)
return return
end end
local playername = player:get_player_name() local playername = player:get_player_name()
mcl_player.player_set_skin(player, mcl_skins.skins[playername] .. ".png", mcl_skins.previews[playername] .. ".png") mcl_player.player_set_skin(player, mcl_skins.skins[playername] .. ".png")
end end
-- load player skin on join -- load player skin on join
@ -259,7 +241,11 @@ function mcl_skins.show_formspec(playername)
formspec = formspec .. ";" .. selected .. ";false]" formspec = formspec .. ";" .. selected .. ";false]"
formspec = formspec .. "image[0,0;1.35,2.7;" .. mcl_skins.previews[playername] .. ".png]" local player = minetest.get_player_by_name(playername)
if player then
--maybe the function could accept both player object and player name?
formspec = formspec .. mcl_player.get_player_formspec_model(player, 0, 0, 1.35, 2.7, "mcl_skins:skin_select")
end
if meta then if meta then
if meta.name and meta.name ~= "" then if meta.name and meta.name ~= "" then

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

View File

@ -101,9 +101,6 @@ fire_animation_frames (Fire Animation Frames) int 8
# Whether to animate chests when open / close # Whether to animate chests when open / close
animated_chests (Animated chests) bool true animated_chests (Animated chests) bool true
# Whether to preview the player in inventory in 3D (requires Minetest 5.4)
3d_player_preview (3D Player preview) bool true
# The maximum number of boss bars to simultaniously display on the screen # The maximum number of boss bars to simultaniously display on the screen
max_bossbars (Maximum Boss bars) int 5 max_bossbars (Maximum Boss bars) int 5