fixes and addons

master
root 2021-08-18 02:16:20 +02:00
parent b7d63b5308
commit b62ef00410
43 changed files with 949 additions and 45 deletions

View File

@ -34,7 +34,8 @@ function closet.compose_preview(clicker, gender)
if not(underwear) then
lower = "cloth_lower_underwear_preview.png"
end
local base_texture = player_api.compose_base_texture(clicker, {
local _base_texture = player_api.get_base_texture_table(clicker)
local base_texture = player_api.compose_base_texture(_base_texture, {
canvas_size ="32x64",
skin_texture = "closet_player_preview.png",
eyebrowns_pos = "8,0",

View File

@ -3,7 +3,9 @@ local S = ...
function vanity.get_vanity_formspec(clicker)
--5.4--local model = player_api.get_gender_model(gender)
local face_preview = minetest.formspec_escape(player_api.compose_base_texture(clicker, {
local _base_texture = player_api.get_base_texture_table(clicker)
local face_preview = minetest.formspec_escape(player_api.compose_base_texture(_base_texture, {
canvas_size ="16x16",
skin_texture = "vanity_face_base.png",
eyebrowns_pos = "0,0",

View File

@ -1,12 +1,13 @@
elez = {}
local coin_name = "elez:electrum"
elez.coin_name = "elez:electrum"
elez.coin_symbol = "ê"
local ingots_to_coins = 99
local withdraw_max = 99
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
--Electrum
minetest.register_craftitem(coin_name, {
minetest.register_craftitem(elez.coin_name, {
description = S("Electrum"),
inventory_image = "elez_electrum.png",
wield_image = "elez_electrum.png",
@ -15,7 +16,7 @@ minetest.register_craftitem(coin_name, {
minetest.register_craft({
type = "shaped",
output = coin_name.." "..tostring(ingots_to_coins),
output = elez.coin_name.." "..tostring(ingots_to_coins),
recipe = {
{"", "moreores:silver_ingot", ""},
{"moreores:silver_ingot", "default:gold_ingot", "moreores:silver_ingot"},
@ -79,7 +80,7 @@ minetest.register_craft({
type = "shaped",
output = "elez:piggy_bank",
recipe = {
{"", coin_name, ""},
{"", elez.coin_name, ""},
{"", "dye:pink", ""},
{"", "default:clay", ""},
}
@ -151,14 +152,14 @@ function elez.save_money(player)
local inv = player:get_inventory()
local inv_list = inv:get_list("main")
local player_name = player:get_player_name()
if not inv:contains_item("main", coin_name) then
if not inv:contains_item("main", elez.coin_name) then
minetest.chat_send_player(player_name, S("You have no electrums in your inventory."))
return false
end
local amount = 0
for i = 1, #inv_list do
local item_stack = inv_list[i]
if item_stack:get_name() == coin_name then
if item_stack:get_name() == elez.coin_name then
amount = amount + item_stack:get_count()
inv:set_stack("main", i, ItemStack(nil))
end
@ -210,7 +211,7 @@ function elez.withdraw_money(player, amount)
return false, S("Error: You has not").." "..tostring(amount).." "..S("of money to withdraw.")
end
local inv = player:get_inventory()
local money_stack = ItemStack(coin_name.." "..tostring(amount))
local money_stack = ItemStack(elez.coin_name.." "..tostring(amount))
if not inv:room_for_item("main", money_stack) then
return false, S("No space in your inventory for the money.")
else
@ -240,7 +241,7 @@ local function compose_formspec(user, title, msg, default_fields, withdraw)
size[6,5]
label[2.25,0.25;]]..title..[[]
label[0.25,0.75;]]..S("Account Balance")..": "..
tostring(elez.get_money(user)).." ê"..[[]
tostring(elez.get_money(user)).." "..elez.coin_symbol..[[]
field[0.25,1.25;2,1;fld_name;]]..S("Name")..[[:;]]..default_fields["name"]..[[]
field_close_on_enter[fld_name;false]
field[2.25,1.25;1,1;fld_amount;]]..S("Amount")..[[:;]]..default_fields["amount"]..[[]

View File

@ -0,0 +1,4 @@
# Licenses
- Source code: GPLv3.
- Textures: CC BY-SA 4.0

View File

@ -0,0 +1,33 @@
# MerchandZ
Are you tired of complicated and absurd trading mods? Do you want the best trading mod on the market?
If your answer is yes, you are in luck! MerchantZ, the ultimate mod, is here.
## Merchantz
- They are cute characters.
- You can put them in the world and they add themselves to trade with the players.
### Wandering or Fixed
Hold the special key (aux) to spawn a fixed merchantz.
## Simple Trading System
- Click and buy!
## Loots
Register your loots in an easy way. Period.
You can create a "user.lua" file with your loots definitions.
## Edit the merchants
Hold the special key (aux) and rightclick the merchantz. It requires the server priv.
## Licenses
- Code: GPL v3.0
- Textures: CC BY-SA 4.0

521
mods/juanchi/eraz/api.lua Normal file
View File

@ -0,0 +1,521 @@
local S = ...
--Helper Funtions
local function is_table_empty(_table)
return next(_table) == nil
end
local function is_srt_empty(s)
return s == nil or s == ''
end
local function round(x)
return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
end
local function boolean_to_string(var)
if var or var == 1 or var == "true" then
return "true"
elseif not(var) or var == nil or var == 0 or var == "false" then
return "false"
else
return "false"
end
end
eraz.file_exists = function(filename)
local f = io.open(filename, "r")
if f ~= nil then
io.close(f)
return true
else
return false
end
end
--CORE functions
local function set_gender()
local gender
if math.random(2) == 1 then
gender = "male"
else
gender = "female"
end
return gender
end
local function set_cloths()
local cloths = {
head = nil,
upper = "eraz:adventurer_jacket",
lower = nil,
footwear = "eraz:adventurer_boots",
}
return cloths
end
local function set_loot()
if is_table_empty(eraz.loots) then
return nil
end
local keyset = {}
for k in pairs(eraz.loots) do
table.insert(keyset, k)
end
local loot = keyset[math.random(#keyset)]
--minetest.chat_send_all(loot)
return loot
end
local function load_loot(merchant)
local loot = eraz.loots[merchant.loot]
return loot
end
local function update_nick(self)
if self.show_name and self.nick and not(self.nick == "") then
self.object:set_nametag_attributes({
text = self.nick,
bgcolor = "#FFFFFF00",
})
else
self.object:set_nametag_attributes({
text = "",
})
end
end
local function compose_cloth(_base_texture, cloths)
local base_texture = player_api.compose_base_texture(_base_texture, {
canvas_size ="128x64",
skin_texture = "player_skin.png",
eyebrowns_pos = "16,16",
eye_right_pos = "18,24",
eye_left_pos = "26,24",
mouth_pos = "16,28",
hair_preview = false,
hair_pos = "0,0",
})
local cloth = base_texture.."^".."[combine:128x64:0,0="
if cloths.head then
cloth = cloth..":"..player_api.cloth_pos[1].."="
..minetest.registered_craftitems[cloths.head]._cloth_texture
end
if cloths.upper then
cloth = cloth..":"..player_api.cloth_pos[2].."="
..minetest.registered_craftitems[cloths.upper]._cloth_texture
end
if cloths.lower then
cloth = cloth..":"..player_api.cloth_pos[3].."="
..minetest.registered_craftitems[cloths.lower]._cloth_texture
end
if cloths.footwear then
cloth = cloth..":"..player_api.cloth_pos[4].."="
..minetest.registered_craftitems[cloths.footwear]._cloth_texture
end
return cloth
end
function eraz.set_initial_properties(self, staticdata, dtime_s)
if dtime_s == 0 then --new merchant
--self.type already defined when spawned
self.nick = S("Merchant")
self.gender = mobkit.remember(self, "gender", set_gender())
local base_texture = player_api.create_base_texture(self.gender)
self.base_texture = mobkit.remember(self, "base_texture", minetest.serialize(base_texture))
local cloths = set_cloths()
local cloth = compose_cloth(base_texture, cloths)
self.cloth = mobkit.remember(self, "cloth", cloth)
self.loot = mobkit.remember(self, "loot", set_loot())
self.show_name = mobkit.remember(self, "show_name", false)
else
self.cloth = mobkit.recall(self, "cloth")
self.base_texture = mobkit.recall(self, "base_texture")
self.gender = mobkit.recall(self, "gender")
self.loot = mobkit.recall(self, "loot")
self.type = mobkit.recall(self, "type")
self.nick = mobkit.recall(self, "nick") or S("Merchant")
self.show_name = mobkit.recall(self, "show_name") or false
end
local model
if self.gender == "female" then
model = "female.b3d"
else
model = "character.b3d"
end
self.trading = mobkit.remember(self, "trading", false)
self.object:set_properties({
visual = "mesh",
mesh = model,
textures = {self.cloth},
})
if self.type == "fixed" then
self:stand()
end
update_nick(self)
end
function eraz.register_egg(name, desc, inv_img)
local description = S("@1", desc)
minetest.register_craftitem(name.."_set", {
description = description,
inventory_image = inv_img,
groups = {spawn_egg = 2},
stack_max = 1,
on_place = function(itemstack, placer, pointed_thing)
local spawn_pos = pointed_thing.above
local under = minetest.get_node(pointed_thing.under)
local def = minetest.registered_nodes[under.name]
if def and def.on_rightclick then
return def.on_rightclick(pointed_thing.under, under, placer, itemstack)
end
if spawn_pos and not minetest.is_protected(spawn_pos, placer:get_player_name()) then
if not minetest.registered_entities[name] then
return
end
local meta = itemstack:get_meta()
local staticdata = meta:get_string("staticdata")
local ent = minetest.add_entity(spawn_pos, name, staticdata)
local ent_ref = ent:get_luaentity()
local merchant_type
local controls = placer:get_player_control()
if controls.aux1 then
merchant_type = "fixed"
else
merchant_type = "errand"
end
ent_ref.type = mobkit.remember(ent_ref, "type", merchant_type)
if merchant_type == "fixed" then
ent_ref:stand()
end
itemstack:take_item()
end
end,
})
end
function eraz.cancel_trading(self, msg)
local player_name = self.trading
if player_name then
local player = minetest.get_player_by_name(player_name)
if player then
minetest.close_formspec(player_name, "eraz:merchant")
if msg then
minetest.chat_send_player(player_name, msg)
end
end
end
end
local _contexts = {}
local function get_context(name)
local context = _contexts[name] or {}
_contexts[name] = context
return context
end
minetest.register_on_leaveplayer(function(player)
_contexts[player:get_player_name()] = nil
end)
local function get_items_loot(loot)
local items_loot = ""
local items_count = 0
local col = 0
local row = 0
local amount, price
for item, item_def in pairs(eraz.loots[loot].items) do
amount = tostring(item_def.amount or 1)
price = tostring(item_def.price or 0)..elez.coin_symbol
items_loot = items_loot..
"item_image_button["..tostring(col)..","..tostring(row)..";1,1;"..item_def.name..";"..item..";"..amount.."/"..price.."]"
items_count = items_count + 1
if col == 2 then
col = 0
row = row + 1
else
col = col + 1
end
end
return items_loot, items_count
end
local function get_items_basket(player)
local items_basket = ""
local total_cost = 0
local player_name = player:get_player_name()
local context = get_context(player_name)
if is_table_empty(context.basket) then
return items_basket, total_cost
end
local col = 0
local row = 0
local amount, price
for item, item_def in pairs(context.basket) do
amount = tostring(item_def.amount or 1)
price = tostring(item_def.price or 0)..elez.coin_symbol
items_basket = items_basket..
"item_image_button["..tostring(col)..","..tostring(row)
..";1,1;"..item_def.name..";"..item..";"..amount.."/"..price.."]"
total_cost = total_cost + item_def.price
if col == 2 then
col = 0
row = row + 1
else
col = col + 1
end
end
context.total_cost = total_cost
return items_basket, total_cost
end
local function compose_edit_formspec(self, player)
local player_name = player:get_player_name()
local context = get_context(player_name)
local loots = ""
local index
local i = 1
for loot_name in pairs(eraz.loots) do
if i > 1 then
loots = loots..","
end
loots = loots..loot_name
if loot_name == context.merchant.loot then
index = i
end
i = i + 1
end
if not index then
index = 0
end
local selected = "false"
if context.merchant.type == "fixed" then
selected = "true"
end
local formspec = [[
formspec_version[4]
size[6,6]
set_focus[btn_close;]
field[0.5,0.5;3,0.5;ipt_nick;]]..S("Name")..":"..";"..context.merchant.nick..[[]
checkbox[3.75,0.75;chk_show_name;]]..S("Show name")..";"..boolean_to_string(context.merchant.show_name)..[[]
label[0.5,2;]]..S("Loot")..":"..[[]
dropdown[1.5,1.5;3;drpdwn;]]..loots..[[;]]..tostring(index)..[[;]
checkbox[0.5,3;chk_fixed;]]..S("Fixed")..[[;]]..selected..[[]
style[btn_remove;bgcolor=indianred]
button_exit[0.5,3.5;1,1;btn_remove;]]..S("Remove")..[[]
button_exit[2.5,4.5;1,1;btn_close;]]..S("Close")..[[]
]]
return formspec
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "eraz:edit_merchant" then
return
end
local player_name = player:get_player_name()
local context = get_context(player_name)
if fields.drpdwn then
context.merchant.loot = mobkit.remember(context.merchant, "loot", fields.drpdwn)
end
if fields.chk_fixed then
local is_fixed = minetest.is_yes(fields.chk_fixed)
local _type
if is_fixed then
_type = "fixed"
else
_type = "errand"
end
context.merchant.type = mobkit.remember(context.merchant, "type", _type)
if is_fixed then
context.merchant:stand()
end
end
if fields.ipt_nick then
context.merchant.nick = mobkit.remember(context.merchant, "nick", fields.ipt_nick)
update_nick(context.merchant)
end
if fields.chk_show_name then
context.merchant.show_name = mobkit.remember(context.merchant, "show_name",
minetest.is_yes(fields.chk_show_name))
update_nick(context.merchant)
end
if fields.btn_remove then
if context.merchant.trading then
minetest.close_formspec(player_name, "eraz:merchant")
end
eraz.cancel_trading(context.merchant, S("The merchant has been removed."))
context.merchant.object:remove()
end
end)
local function compose_formspec(self, player, msg)
local money = tostring(elez.get_money(player)).." "..elez.coin_symbol
local items_loot, items_count = get_items_loot(self.loot)
local items_basket, total_cost = get_items_basket(player)
total_cost = tostring(total_cost).." "..elez.coin_symbol
local items_count_str = tostring(items_count)
if is_srt_empty(msg) then
msg = ""
end
local face = player_api.get_face(minetest.deserialize(self.base_texture), 1.0, true)
local formspec = [[
formspec_version[4]
size[8.25,8.25]
image[0.5,0.25;0.5,0.5;]]..face..[[]
label[1.25,0.5;]]..self.nick..[[]
label[0.5,1;]]..items_count_str.." "..S("items(s)")
.." | "..S("Amount/Price")..[[]
label[0.5,4.5;]]..S("Click to add to the basket")..[[]
label[4.25,4.5;]]..S("Click to delete from the basket")..[[]
label[5.25,0.75;]]..S("Money")..":".." "..money..[[]
image[4.5,0.625;0.5,0.5;eraz_basket.png]
label[5.25,1;]]..S("Cost")..":".." "..total_cost..[[]
box[0.5,1.25;3,3;darkgray]
scroll_container[0.5,1.25;3,3;scroll_buy;vertical;]
]]..items_loot..[[
scroll_container_end[]
scrollbaroptions[min=0;max=]]..tostring(round(items_count))
..[[;smallstep=]]..items_count_str..[[;largestep=]]..items_count_str..[[]
style_type[scroll_buy;bgcolor=#446699]
scrollbar[3.5,1.25;0.5,3;vertical;scroll_buy;0]
box[4.25,1.25;3,3;darkgray]
scroll_container[4.25,1.25;3,3;scroll_basket;vertical;]
]]..items_basket..[[
scroll_container_end[]
scrollbaroptions[min=0;max=]]..tostring(round(items_count))
..[[;smallstep=]]..items_count_str..[[;largestep=]]..items_count_str..[[]
scrollbar[7.25,1.25;0.5,3;vertical;scroll_basket;0]
button_exit[5.125,5;1,1;btn_buy;]]..S("Buy")..[[]
label[0.5,6.5;]]..msg..[[]
button_exit[3.25,6.75;1,1;btn_close;]]..S("Close")..[[]
]]
return formspec
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "eraz:merchant" then
return
end
local player_name = player:get_player_name()
local context = get_context(player_name)
local item, item_def
local action
--minetest.chat_send_all(minetest.serialize(fields))
for key, value in pairs(fields) do
if not(key=="scroll_buy") and not(key=="scroll_basket") and not(key=="quit")
and not(key=="btn_close") and not(key=="btn_buy") then
item = key
if string.sub(key, 1, 8) == "_BASKET_" then
action = "delete"
item_def = context.basket[item]
else
action = "buy"
item_def = eraz.loots[context.merchant.loot].items[key]
end
break
end
end
if item then
if action == "buy" then
item = "_BASKET_"..item
if context.basket[item] then --already in the basket=>only increase amount
context.basket[item].amount = context.basket[item].amount + item_def.amount
context.basket[item].price = context.basket[item].price + item_def.price
else --new
context.basket[item] = {
name = item_def.name,
price = item_def.price,
amount = item_def.amount,
}
end
else --action = "delete"
context.total_cost = context.total_cost - context.basket[item].price
context.basket[item] = nil
end
minetest.show_formspec(player_name, "eraz:merchant",
compose_formspec(context.merchant, player))
return
end
if fields.btn_buy then
local msg
if context.total_cost <= 0 then
msg = S("You have not selected products to buy!")
elseif elez.get_money(player) < context.total_cost then
msg = S("You have not enough money!")
else
local inv = player:get_inventory()
local item_stack
local cost = 0
for _item, _item_def in pairs(context.basket) do
item_stack = ItemStack(_item_def.name.." "..tostring(_item_def.amount))
if inv:room_for_item("main", item_stack) then
inv:add_item("main", item_stack)
context.basket[_item] = nil
elez.add_money(player, -_item_def.price)
cost = cost + _item_def.price
context.total_cost = context.total_cost - _item_def.price
end
end
msg = S("You have purchased products with a value of").." "
..tostring(cost).." "..elez.coin_symbol
end
minetest.show_formspec(player_name, "eraz:merchant",
compose_formspec(context.merchant, player, msg))
return
end
context.merchant.trading = false
end)
local function load_shop(self, player)
local player_name = player:get_player_name()
local loot = load_loot(self)
if not loot then
minetest.chat_send_player(player_name, S("This merchant has not loot."))
return
end
local context = get_context(player_name)
context.merchant = self
context.basket = {}
context.total_cost = 0
minetest.show_formspec(player_name, "eraz:merchant",
compose_formspec(self, player))
self.trading = player_name
if self.type == "errand" then
self:stand() --stop merchant
end
end
local function edit_merchant(self, player)
local player_name = player:get_player_name()
local context = get_context(player_name)
context.merchant = self
minetest.show_formspec(player_name, "eraz:edit_merchant",
compose_edit_formspec(self, player))
end
function eraz.register_loot(name, def)
if not eraz.loots[name] then
eraz.loots[name] = def
end
end
function eraz.on_rightclick(self, player)
local controls = player:get_player_control()
local has = minetest.check_player_privs(player, {
server = true,
})
if has and controls.aux1 then
edit_merchant(self, player)
return
end
if self.trading then
minetest.chat_send_player(player:get_player_name(), S("This merchant is already trading with another player."))
return
else
load_shop(self, player)
return
end
end

View File

@ -0,0 +1,37 @@
-- The Brain of the Merchant
--
function eraz.merchant_brain(self)
--local pos = self.object:get_pos()
mobkit.vitals(self)
if self.hp <= 0 then
self:on_die()
return
end
if mobkit.timer(self, 1) then
local prty = mobkit.get_queue_priority(self)
if prty < 30 then
if self.isinliquid then
mobkit.hq_liquid_recovery(self, 30)
return
end
end
--local player = mobkit.get_nearby_player(self)
--minetest.chat_send_all("test")
--Wandering default
if mobkit.is_queue_empty_high(self) and self.type == "errand"
and not(self.trading) then
mobkit.hq_roam(self, 0)
end
end
end

View File

@ -0,0 +1,25 @@
local S = ...
--Adventurer Jacket
player_api.register_cloth("eraz:adventurer_jacket", {
description = S("Adventurer Jacket"),
texture = "eraz_adventurer_jacket.png",
inventory_image = "eraz_adventurer_jacket_inv.png",
wield_image = "eraz_adventurer_jacket_inv.png",
preview = "eraz_adventurer_jacket_preview.png",
gender = "unisex",
groups = {cloth = 2},
})
--Adventurer Boots
player_api.register_cloth("eraz:adventurer_boots", {
description = S("Adventurer Boots"),
texture = "eraz_adventurer_boots.png",
inventory_image = "eraz_adventurer_boots_inv.png",
wield_image = "eraz_adventurer_boots_inv.png",
preview = "eraz_adventurer_boots_preview.png",
gender = "unisex",
groups = {cloth = 4},
})

View File

@ -0,0 +1,20 @@
--
-- Eraz
--
eraz = {}
eraz.loots = {}
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
assert(loadfile(modpath .. "/api.lua"))(S)
assert(loadfile(modpath .. "/loots.lua"))()
assert(loadfile(modpath .. "/brain_merchant.lua"))()
assert(loadfile(modpath .. "/merchant.lua"))(S)
assert(loadfile(modpath .. "/cloth.lua"))(S)
local user_file = modpath .. "/user.lua"
if eraz.file_exists(user_file) then
assert(loadfile(user_file))()
end

View File

@ -0,0 +1,24 @@
# textdomain: eraz
Merchant=Mercader
Money=Dinero
Cost=Coste
item(s)=producto(s)
Amount/Price=Cantidad/Precio
Click to add to the basket=Clic para añadir a la cesta
Click to delete from the basket=Clic para eliminar de la cesta
Buy=Comprar
Close=Cerrar
Name=Nombre
Loot=Lote
Fixed=Estático
Remove=Eliminar
Show name=Mostrar nombre
This merchant has not loot.=Este mercader no tiene nada que vender.
The merchant has been removed.=El mercader ha sido eliminado.
The merchant has died.=El mercader ha muerto.
This merchant is already trading with another player.=Este mercader ya está comerciando con otro jugador.
You have purchased products with a value of=Has comprado productos por valor de
You have not enough money!=¡No tienes suficiente dinero!
You have not selected products to buy!=No has seleccionado productos para comprar
Adventurer Jacket=Chaqueta de aventurero
Adventurer Boots=Botas de aventurero

View File

@ -0,0 +1,15 @@
eraz.register_loot("basic_food", {
type = "fixed",
items = {
apple = {
name = "default:apple",
price = 3,
amount = 6,
},
bread = {
name = "farming:bread",
price = 1,
amount = 1,
},
},
})

View File

@ -0,0 +1,64 @@
--
-- ERRAND MERCHANTS
--
local S = ...
minetest.register_entity("eraz:merchant",{
type = "errand",
genre = "male",
visual = "mesh",
mesh = "character.b3d",
textures = {"character.png"},
visual_size = {x= 1.0, y= 1.0},
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
static_save = true,
physical = true,
collide_with_objects = true,
-- mod props
-- mobkit api props
get_staticdata = mobkit.statfunc,
stepheight = 0.1, --EVIL!
springiness = 0,
buoyancy = 0.5, -- portion of hitbox submerged
max_speed = 3,
jump_height = 1,
view_range = 10,
lung_capacity = 10, -- seconds
max_hp = 20,
attack = {range=0.5, damage_groups = {fleshy=3}},
animation = {
stand = {range= { x= 0, y= 79}, speed= 5, loop= true},
walk = {range= { x= 168, y= 187}, speed= 25, loop= true},
},
logic = eraz.merchant_brain,
on_activate = function(self, staticdata, dtime_s) --on_activate, required
mobkit.actfunc(self, staticdata, dtime_s)
eraz.set_initial_properties(self, staticdata, dtime_s)
end,
on_step = function(self, dtime)
mobkit.stepfunc(self, dtime) -- required
end,
on_rightclick = function(self, clicker)
eraz.on_rightclick(self, clicker)
end,
stand = function(self)
mobkit.clear_queue_low(self)
mobkit.clear_queue_high(self)
mobkit.animate(self, "stand")
end,
on_die = function(self)
eraz.cancel_trading(self, S("The merchant has died."))
end,
})
eraz.register_egg("eraz:merchant", S("Merchant"), "eraz_spawnegg_merchant.png", false)

View File

@ -0,0 +1,3 @@
name = eraz
description = Errand Merchants
depends = player_api, elez

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -101,7 +101,7 @@ minetest.register_on_joinplayer(function(player, last_login)
end)
minetest.register_on_leaveplayer(function(player, timed_out)
meta:set_int("invz:play_time", get_play_time(player))
player:get_meta():set_int("invz:play_time", get_play_time(player))
end)
sfinv.register_page("server", {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -13,9 +13,9 @@ local function create_form()
for _, player in ipairs(minetest.get_connected_players()) do
local player_name = player:get_player_name()
local player_face
if player_api.get_gender(player) then
player_face = player_api.compose_face(player, 2.0)
player_face = minetest.formspec_escape(player_face)
if player_api.get_gender(player) ~= "" then
local base_texture = player_api.get_base_texture_table(player)
player_face = player_api.get_face(base_texture, 2.0, true)
else
player_face = "player_male_face.png"
end

View File

@ -213,7 +213,9 @@ Diamond Sword=Diamantschwert
Key=Schlüssel
Torch=Fackel
@1 will intersect protection on growth.=@1 wird bei Wachstum mit geschützter Zone überlappen.
Brazilwood=Brasilholz
Buddha's Hand=Buddhas Hand
Bird of Paradise=Paradiesvogel
##### not used anymore #####

View File

@ -214,7 +214,9 @@ Diamond Sword=Espada de diamante
Key=Llave
Torch=Antorcha
@1 will intersect protection on growth.=@1 intersectará con protección cuando crezca.
Brazilwood=Palo de Brasil
Buddha's Hand=Mano de Buda
Bird of Paradise=Pájaro del paraíso
##### not used anymore #####

View File

@ -150,7 +150,7 @@ Pink Coral=Corail rose
Cyan Coral=Corail cyan
Brown Coral=Corail marron
Orange Coral=Corail orange
Coral Skeleton=Squelette de corail
Coral Skeleton=Squelette de corail
Water Source=Source d'eau
Flowing Water=Ecoulement d'eau
River Water Source=Source d'eau de rivière
@ -213,7 +213,9 @@ Diamond Sword=Epée en diamant
Key=Clé
Torch=Torche
@1 will intersect protection on growth.=@1 chevauchera la zone protégée avec la croissance.
Brazilwood=Bois de Brésil
Buddha's Hand=Main de Bouddha
Bird of Paradise=Oiseau de Paradis
##### not used anymore #####

View File

@ -213,7 +213,9 @@ Diamond Sword=Spada di diamante
Key=Chiave
Torch=Torcia
@1 will intersect protection on growth.=@1 crescendo attraverserà la protezione.
Brazilwood=Legno del Brasile
Buddha's Hand=Mano di Buddha
Bird of Paradise=Uccello del paradiso
##### not used anymore #####

View File

@ -213,3 +213,6 @@ Diamond Sword=Espada de Diamante
Key=Chave
Torch=Tocha
@1 will intersect protection on growth.=@1 cruzará a proteção no crescimento.
Brazilwood=Paubrasilia
Buddha's Hand=Mano de Buda
Bird of Paradise=Ave do Paraíso

View File

@ -35,7 +35,7 @@ Stick=Палка
Tin Ingot=Оловянный Слиток
Tin Lump=Кусок Олова
Furnace is empty=Печь пуста
100% (output full)=100% (полное приготовление)
100% (output full)=100% (полное приготовление)
@1%=@1%
Not cookable=Не может быть приготовлено
Empty=Пустое
@ -213,7 +213,9 @@ Diamond Sword=Алмазный Меч
Key=Ключ
Torch=Факел
@1 will intersect protection on growth.=@1 пересечёт защиту по росту.
Brazilwood=бразильское дерево
Buddha's Hand=Рука Будды
Bird of Paradise=Райская птица
##### not used anymore #####

View File

@ -2318,6 +2318,72 @@ function default.register_decorations()
flags= "all_floors",
})
-- Brazilwood
minetest.register_decoration({
name = "default:brazilwood",
decoration = "default:brazilwood",
deco_type = "simple",
biomes = {"rainforest"},
place_on = {"default:dirt_with_rainforest_litter"},
sidelen = 16,
noise_params = {
offset = 0.016,
scale = 0.016,
spread = {x = 20, y = 20, z = 20},
seed = 589,
octaves = 3,
persist = 0.7
},
y_max = 31000,
y_min = 1,
flags= "all_floors",
})
-- Alocasia
minetest.register_decoration({
name = "default:alocasia",
decoration = "default:alocasia",
deco_type = "simple",
biomes = {"rainforest"},
place_on = {"default:dirt_with_rainforest_litter"},
sidelen = 16,
noise_params = {
offset = 0.016,
scale = 0.016,
spread = {x = 20, y = 20, z = 20},
seed = 458,
octaves = 3,
persist = 0.7
},
y_max = 31000,
y_min = 1,
flags= "all_floors",
})
-- Bird of Paradise
minetest.register_decoration({
name = "default:bird_paradise",
decoration = "default:bird_paradise",
deco_type = "simple",
biomes = {"rainforest"},
place_on = {"default:dirt_with_rainforest_litter"},
sidelen = 16,
noise_params = {
offset = 0.016,
scale = 0.016,
spread = {x = 20, y = 20, z = 20},
seed = 82,
octaves = 3,
persist = 0.7
},
y_max = 31000,
y_min = 1,
flags= "all_floors",
})
-- Sunflower
minetest.register_decoration({

View File

@ -1476,6 +1476,63 @@ minetest.register_node("default:bioluminiscent_plant", {
},
})
minetest.register_node("default:brazilwood", {
description = S("Brazilwood"),
drawtype = "plantlike",
tiles = {"default_brazilwood.png"},
visual_scale = 1.25,
inventory_image = "default_brazilwood.png",
wield_image = "default_brazilwood.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
buildable_to = true,
groups = {snappy = 3, flammable = 3, flower =1, flora=1, attached_node = 1},
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 3.5 / 16, 4 / 16},
},
})
minetest.register_node("default:alocasia", {
description = S("Buddha's Hand"),
drawtype = "plantlike",
tiles = {"default_alocasia.png"},
visual_scale = 1.05,
inventory_image = "default_alocasia.png",
wield_image = "default_alocasia.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
buildable_to = true,
groups = {snappy = 3, flammable = 3, flower =1, flora=1, attached_node = 1},
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 3.5 / 16, 4 / 16},
},
})
minetest.register_node("default:bird_paradise", {
description = S("Bird of Paradise"),
drawtype = "plantlike",
tiles = {"default_bird_paradise.png"},
visual_scale = 1.5,
inventory_image = "default_bird_paradise.png",
wield_image = "default_bird_paradise.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
buildable_to = true,
groups = {snappy = 3, flammable = 3, flower =1, flora=1, attached_node = 1},
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 3.5 / 16, 4 / 16},
},
})
minetest.register_node("default:junglegrass", {
description = S("Jungle Grass"),
drawtype = "plantlike",

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -2,7 +2,7 @@
local stuff_string = minetest.settings:get("initial_stuff") or
"default:pick_wood,default:axe_wood,default:shovel_wood,default:apple,"..
"farming:breadº"
"farming:bread"
give_initial_stuff = {
items = {}

View File

@ -369,8 +369,19 @@ function player_api.set_texture(player)
player_api.set_textures(player, models[gender_model].textures)
end
function player_api.compose_face(player, scale)
return player_api.compose_base_texture(player, {
function player_api.get_face(base_texture, scale, escape)
if not scale then
scale = 1.0
end
local face = player_api.compose_face(base_texture, scale)
if escape then
face = minetest.formspec_escape(face)
end
return face
end
function player_api.compose_face(base_texture, scale)
return player_api.compose_base_texture(base_texture, {
canvas_size = "16x16",
scale = scale,
skin_texture = "player_face_skin.png",

View File

@ -3,7 +3,7 @@ player_api.hair_colors = {
color = "#000000",
ratio = 175,
},
gray = nil,
gray = {},
light_brown = {
color = "#7a4c20",
ratio = 150,
@ -65,10 +65,8 @@ function player_api.set_base_texture(player, base_texture)
meta:set_string("base_texture", minetest.serialize(base_texture))
end
function player_api.set_base_textures(player)
local meta = player:get_meta()
function player_api.create_base_texture(gender)
local base_texture = {}
local gender = meta:get_string("gender")
local hair_color = hair_colors_redux[math.random(#hair_colors_redux)]
local eye_color = "player_"..player_api.eye_colors[math.random(#player_api.eye_colors)].."_eye.png"
if gender == "male" then
@ -84,11 +82,17 @@ function player_api.set_base_textures(player)
end
base_texture["skin"] = {texture = "player_skin.png", color =
skin_colors_redux[math.random(#skin_colors_redux)]}
return base_texture
end
function player_api.set_base_textures(player)
local meta = player:get_meta()
local gender = meta:get_string("gender")
local base_texture = player_api.create_base_texture(gender)
player_api.set_base_texture(player, base_texture)
end
function player_api.colorize_texture(player, what, texture)
local base_texture = player_api.get_base_texture_table(player)
local function colorize_texture(base_texture, what, texture)
if base_texture[what]["color"] then
local value
if what == "skin" then
@ -96,7 +100,7 @@ function player_api.colorize_texture(player, what, texture)
else --"hair"
value = player_api.hair_colors[base_texture[what]["color"]]
end
if value then
if value and value.color then
return texture .. "\\^\\[colorize\\:\\"..value.color.."\\:"..tostring(value.ratio)
else
return texture
@ -106,9 +110,9 @@ function player_api.colorize_texture(player, what, texture)
end
end
function player_api.compose_base_texture(player, def)
local base_texture = player_api.get_base_texture_table(player)
local texture = player_api.colorize_texture(player, "skin", "[combine:"..def.canvas_size..":0,0="..def.skin_texture)
function player_api.compose_base_texture(base_texture, def)
local texture = colorize_texture(base_texture, "skin", "[combine:"..def.canvas_size..":0,0="..def.skin_texture)
local ordered_keys = {}
@ -121,7 +125,7 @@ function player_api.compose_base_texture(player, def)
for i = 1, #ordered_keys do
local key, value = ordered_keys[i], base_texture[ordered_keys[i]]
if key == "eyebrowns" then
value.texture = player_api.colorize_texture(player, "eyebrowns", value.texture)
value.texture = colorize_texture(base_texture, "eyebrowns", value.texture)
texture = texture .. ":"..def.eyebrowns_pos.."="..value.texture
elseif key == "eye" then
texture = texture .. ":"..def.eye_right_pos.."="..value
@ -132,7 +136,7 @@ function player_api.compose_base_texture(player, def)
if def.hair_preview then
value.texture = string.sub(value.texture, 0, -5).."_preview.png"
end
value.texture = player_api.colorize_texture(player, "hair", value.texture)
value.texture = colorize_texture(base_texture, "hair", value.texture)
texture = texture .. ":"..def.hair_pos.."="..value.texture
end
end

View File

@ -134,7 +134,7 @@ function player_api.set_cloths(player)
inv:add_item("cloths", 'player_api:cloth_unisex_footwear_default')
end
local cloth_pos = {
player_api.cloth_pos = {
"48,0",
"32,32",
"0,32",
@ -170,7 +170,8 @@ function player_api.compose_cloth(player)
if not(underwear) then
lower_ItemStack = "cloth_lower_underwear_default.png"
end
local base_texture = player_api.compose_base_texture(player, {
local _base_texture = player_api.get_base_texture_table(player)
local base_texture = player_api.compose_base_texture(_base_texture, {
canvas_size ="128x64",
skin_texture = "player_skin.png",
eyebrowns_pos = "16,16",
@ -182,16 +183,16 @@ function player_api.compose_cloth(player)
})
local cloth = base_texture.."^".."[combine:128x64:0,0="
if head_ItemStack then
cloth = cloth .. ":"..cloth_pos[1].."="..head_ItemStack
cloth = cloth .. ":"..player_api.cloth_pos[1].."="..head_ItemStack
end
if upper_ItemStack then
cloth = cloth .. ":"..cloth_pos[2].."="..upper_ItemStack
cloth = cloth .. ":"..player_api.cloth_pos[2].."="..upper_ItemStack
end
if lower_ItemStack then
cloth = cloth .. ":"..cloth_pos[3].."="..lower_ItemStack
cloth = cloth .. ":"..player_api.cloth_pos[3].."="..lower_ItemStack
end
if footwear_ItemStack then
cloth = cloth .. ":"..cloth_pos[4].."="..footwear_ItemStack
cloth = cloth .. ":"..player_api.cloth_pos[4].."="..footwear_ItemStack
end
--Now attached cloth
if not(next(attached_cloth) == nil) then
@ -199,7 +200,7 @@ function player_api.compose_cloth(player)
local attached_item_name = attached_cloth[i]
local attached_itemstack = minetest.registered_items[attached_item_name]
local attached_cloth_type = minetest.get_item_group(attached_item_name, "cloth")
cloth = cloth .. ":"..cloth_pos[attached_cloth_type].."="..attached_itemstack._cloth_texture
cloth = cloth .. ":"..player_api.cloth_pos[attached_cloth_type].."="..attached_itemstack._cloth_texture
end
end
return cloth

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -13,8 +13,10 @@ minetest.register_entity("petz:wagon",{
physical= true,
collisionbox = {-0.5, -1.5, -1.75, 0.5, -0.25, -3.0},
hitbox = {-0.5, -1.5, -1.5, 0.5, -0.25, -3.0},
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
mokapi.drop_item(self, "petz:wagon", 1)
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
if self.object:get_hp() - damage <= 0 then
mokapi.drop_item(self, "petz:wagon", 1)
end
end,
})