183 lines
No EOL
7.2 KiB
Lua
183 lines
No EOL
7.2 KiB
Lua
-- Research level group bonus
|
|
if researcher.settings.group_research_bonus > 0 and researcher.settings.group_research_bonus_max > 0 then
|
|
researcher.register_bonus({
|
|
name = "researcher:research_group_research_bonus",
|
|
reason = "Group Research",
|
|
calculate = function(item,player_data)
|
|
local bonus = 0
|
|
for subject,research in pairs(player_data.research) do
|
|
if researcher.do_items_share_groups(item,subject) then
|
|
bonus = bonus + (research.level - 1) * researcher.settings.group_research_bonus
|
|
end
|
|
end
|
|
return bonus
|
|
end,
|
|
initialize_player_data = function()
|
|
-- all bonus calculation comes from research; nothing to initialize
|
|
end,
|
|
})
|
|
else
|
|
researcher.register_bonus({
|
|
name = "researcher:research_group_research_bonus",
|
|
reason = "Group Research",
|
|
calculate = function() return 0 end,
|
|
initialize_player_data = function()
|
|
-- bonus is calculated from research; nothing to initialize
|
|
end,
|
|
})
|
|
end
|
|
|
|
-- Focused research bonus
|
|
if researcher.settings.focused_research_bonus_max > 0 and (researcher.settings.focused_research_bonus_exact > 0 or researcher.settings.focused_research_bonus_group > 0) then
|
|
researcher.register_bonus({
|
|
name = "researcher:focused_research_bonus",
|
|
reason = "Focused Research",
|
|
calculate = function(item,player_data)
|
|
-- Calculate bonus value
|
|
if item == player_data.focused_research.item then
|
|
player_data.focused_research.bonus = player_data.focused_research.bonus + researcher.settings.focused_research_bonus_exact
|
|
elseif researcher.do_items_share_groups(item,player_data.focused_research.item) then
|
|
player_data.focused_research.bonus = player_data.focused_research.bonus + researcher.settings.focused_research_bonus_group
|
|
else
|
|
player_data.focused_research.bonus = 0
|
|
end
|
|
|
|
-- Set focused item
|
|
player_data.focused_research.item = item
|
|
|
|
-- Return capped bonus value
|
|
player_data.focused_research.bonus = math.min(player_data.focused_research.bonus,researcher.settings.focused_research_bonus_max)
|
|
return player_data.focused_research.bonus
|
|
end,
|
|
initialize_player_data = function(player_data)
|
|
player_data.focused_research = {
|
|
item = "",
|
|
bonus = 0,
|
|
}
|
|
end,
|
|
})
|
|
else
|
|
researcher.register_bonus({
|
|
name = "researcher:focused_research_bonus",
|
|
reason = "Focused Research",
|
|
calculate = function() return 0 end,
|
|
initialize_player_data = function(player_data)
|
|
player_data.focused_research = {
|
|
item = "",
|
|
bonus = 0,
|
|
}
|
|
end,
|
|
})
|
|
end
|
|
|
|
-- Research table bonus
|
|
if researcher.settings.research_table_bonus_exact > 0 or researcher.settings.research_table_bonus_group > 0 or (researcher.settings.research_table_adjacency_bonus > 0 and researcher.settings.research_table_adjacency_max > 0) then
|
|
researcher.register_bonus({
|
|
name = "researcher:research_table_bonus",
|
|
reason = "Research Table",
|
|
calculate = function(item,player_data)
|
|
-- Initialize bonus and max flag
|
|
local bonus = 0
|
|
local bonusmax = false
|
|
|
|
-- Track limits when tallying bonuses
|
|
local nadj = 0
|
|
local function rtbonus(bonus,increment,adjacency)
|
|
local result = bonus
|
|
if adjacency then
|
|
local adj_bounded = math.min(adjacency,researcher.settings.research_table_adjacency_max - nadj)
|
|
nadj = nadj + adj_bounded
|
|
result = result + researcher.settings.research_table_adjacency_bonus * adj_bounded
|
|
else
|
|
result = bonus + increment
|
|
end
|
|
return math.min(result,researcher.settings.research_table_bonus_max), (result >= researcher.settings.research_table_bonus_max or nadj >= researcher.settings.research_table_adjacency_max)
|
|
end
|
|
|
|
-- Scan radius around player for research tables
|
|
local player = minetest.get_player_by_name(player_data.name)
|
|
local research_table = nil
|
|
if player then
|
|
local pos = player:get_pos()
|
|
local radius = researcher.settings.research_table_player_radius
|
|
for _,rt in ipairs(minetest.find_nodes_in_area(pos:add(-radius),pos:add(radius),"researcher:research_table")) do
|
|
-- Get research table's focus
|
|
local meta = minetest.get_meta(rt)
|
|
local inventory = meta:get_inventory()
|
|
local itemstack = inventory:get_stack("focus",1)
|
|
local name = itemstack:get_name()
|
|
|
|
-- If the focus item matches the item in question, then add to the
|
|
-- calculated bonus accordingly
|
|
if item == name then
|
|
bonus, bonusmax = rtbonus(bonus,(research_table and (researcher.settings.research_table_bonus_exact - researcher.settings.research_table_bonus_group) or researcher.settings.research_table_bonus_exact))
|
|
if bonusmax then
|
|
return bonus
|
|
end
|
|
research_table = rt
|
|
break -- cannot do better than an exact match
|
|
elseif not research_table and researcher.do_items_share_groups(item,name) then
|
|
bonus, bonusmax = rtbonus(bonus,researcher.settings.research_table_bonus_group)
|
|
if bonusmax then
|
|
return bonus
|
|
end
|
|
research_table = rt
|
|
-- keep scanning for better matches
|
|
end
|
|
end
|
|
|
|
-- Calculate adjacency bonus for research table
|
|
if research_table then
|
|
local radius = researcher.settings.research_table_adjacency_radius
|
|
local pos1 = research_table:add(-radius)
|
|
local pos2 = research_table:add(radius)
|
|
|
|
-- Check nearby node groups
|
|
bonus, bonusmax = rtbonus(bonus,researcher.settings.research_table_adjacency_bonus,#minetest.find_nodes_in_area(pos1,pos2,(function()
|
|
local groups = {}
|
|
for group,_ in pairs(researcher.registered_items[item].groups) do
|
|
table.insert(groups,"group:" .. group)
|
|
end
|
|
return groups
|
|
end)()))
|
|
if bonusmax then
|
|
return bonus
|
|
end
|
|
|
|
-- Check nearby node inventories
|
|
for _,node in ipairs(minetest.find_nodes_with_meta(pos1,pos2)) do
|
|
if not node:equals(research_table) then
|
|
local nodemeta = minetest.get_meta(node)
|
|
local nodeinventory = nodemeta:get_inventory()
|
|
if nodeinventory then
|
|
for list,stacks in pairs(nodeinventory:get_lists() or {}) do
|
|
for _,itemstack in ipairs(stacks or {}) do
|
|
if not itemstack:is_empty() and researcher.do_items_share_groups(item,itemstack:get_name()) then
|
|
bonus, bonusmax = rtbonus(bonus,researcher.settings.research_table_adjacency_bonus,itemstack:get_count())
|
|
if bonusmax then
|
|
return bonus
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
return 0 -- no bonus if no research table was found
|
|
end
|
|
else
|
|
return 0 -- no bonus if player is mysteriously not found
|
|
end
|
|
|
|
-- Return partial bonus total
|
|
return bonus
|
|
end,
|
|
})
|
|
else
|
|
researcher.register_bonus({
|
|
name = "researcher:research_table_bonus",
|
|
reason = "Research Table",
|
|
calculate = function() return 0 end,
|
|
})
|
|
end |