Update - 1.7.0.89

EN: 1.7.0.89
CN: 1.7.0.91
JP: 1.7.0.92
KR: 1.7.0.95
This commit is contained in:
SL1900
2026-02-28 15:00:00 +09:00
parent 86d82306fe
commit e01012cbcc
92 changed files with 1562 additions and 936 deletions
+41 -151
View File
@@ -920,41 +920,6 @@ function DispatchCtrl:can_meet_requirements(role_tags, requirements)
end
return true
end
function DispatchCtrl:calculate_role_score(role_tags, normal_req, extra_req)
local score = 0
local tag_count = {}
for _, tag in ipairs(role_tags) do
tag_count[tag] = (tag_count[tag] or 0) + 1
end
for _, req in ipairs(normal_req) do
if tag_count[req] and 0 < tag_count[req] then
score = score + 10
tag_count[req] = tag_count[req] - 1
end
end
for _, req in ipairs(extra_req) do
if tag_count[req] and 0 < tag_count[req] then
score = score + 3
tag_count[req] = tag_count[req] - 1
end
end
return score
end
function DispatchCtrl:count_remaining_requirements(selected_tags, requirements)
local tag_count = {}
for _, tag in ipairs(selected_tags) do
tag_count[tag] = (tag_count[tag] or 0) + 1
end
local remaining = {}
for _, req in ipairs(requirements) do
if not tag_count[req] or tag_count[req] <= 0 then
table.insert(remaining, req)
else
tag_count[req] = tag_count[req] - 1
end
end
return remaining
end
function DispatchCtrl:concat_tags(selected_roles)
local combined_tags = {}
for _, role in ipairs(selected_roles) do
@@ -964,136 +929,61 @@ function DispatchCtrl:concat_tags(selected_roles)
end
return combined_tags
end
function DispatchCtrl:enumerate_combinations(roles, count, callback)
local n = #roles
if count > n then
return nil
end
local indices = {}
for i = 1, count do
indices[i] = i
end
while true do
local combo = {}
for i = 1, count do
combo[i] = roles[indices[i]]
end
if callback(combo) then
return combo
end
local pos = count
while 1 <= pos and indices[pos] == n - count + pos do
pos = pos - 1
end
if pos < 1 then
break
end
indices[pos] = indices[pos] + 1
for i = pos + 1, count do
indices[i] = indices[i - 1] + 1
end
end
return nil
end
function DispatchCtrl:find_min_roles_greedy(roles, normal_req, extra_req)
if #roles == 0 then
return nil
end
for target_count = 1, 3 do
local result = self:greedy_select_roles_with_limit(roles, normal_req, extra_req, true, target_count)
for count = 1, 3 do
local result = self:enumerate_combinations(roles, count, function(combo)
local tags = self:concat_tags(combo)
return self:can_meet_requirements(tags, normal_req) and self:can_meet_requirements(tags, extra_req)
end)
if result then
return result
end
end
for target_count = 1, 3 do
local result = self:greedy_select_roles_with_limit(roles, normal_req, {}, false, target_count)
for count = 1, 3 do
local result = self:enumerate_combinations(roles, count, function(combo)
local tags = self:concat_tags(combo)
return self:can_meet_requirements(tags, normal_req)
end)
if result then
return result
end
end
return nil
end
function DispatchCtrl:greedy_select_roles_with_limit(roles, normal_req, extra_req, check_both, max_count)
if #normal_req == 0 and #extra_req == 0 then
return {}
end
local scored_roles = {}
for _, role in ipairs(roles) do
local score = self:calculate_role_score(role.tags, normal_req, extra_req)
if 0 < score then
table.insert(scored_roles, {role = role, score = score})
end
end
if #scored_roles == 0 then
return nil
end
table.sort(scored_roles, function(a, b)
return a.score > b.score
end)
return self:try_combinations_greedy(scored_roles, normal_req, extra_req, check_both, max_count)
end
function DispatchCtrl:try_combinations_greedy(scored_roles, normal_req, extra_req, check_both, target_count)
local max_attempts = math.min(100, #scored_roles * target_count)
local attempt_count = 0
local selected = {}
local selected_tags = {}
for _, scored_role in ipairs(scored_roles) do
if target_count <= #selected then
break
end
attempt_count = attempt_count + 1
if max_attempts < attempt_count then
break
end
local remaining_normal = self:count_remaining_requirements(selected_tags, normal_req)
local remaining_extra = self:count_remaining_requirements(selected_tags, extra_req)
if #remaining_normal == 0 and #remaining_extra == 0 then
break
end
local can_help = DispatchCtrl.role_can_help(scored_role.role.tags, remaining_normal, remaining_extra)
if can_help then
table.insert(selected, scored_role.role)
for _, tag in ipairs(scored_role.role.tags) do
table.insert(selected_tags, tag)
end
end
end
if #selected == target_count then
if check_both then
if self:can_meet_requirements(selected_tags, normal_req) and self:can_meet_requirements(selected_tags, extra_req) then
return selected
end
elseif self:can_meet_requirements(selected_tags, normal_req) then
return selected
end
end
if target_count <= 2 and target_count <= #scored_roles then
for start_idx = 1, math.min(5, #scored_roles - target_count + 1) do
attempt_count = attempt_count + 1
if max_attempts < attempt_count then
break
end
local test_selected = {}
local test_tags = {}
table.insert(test_selected, scored_roles[start_idx].role)
for _, tag in ipairs(scored_roles[start_idx].role.tags) do
table.insert(test_tags, tag)
end
for i = 1, #scored_roles do
if target_count <= #test_selected then
break
end
if i ~= start_idx then
local remaining_normal = self:count_remaining_requirements(test_tags, normal_req)
local remaining_extra = self:count_remaining_requirements(test_tags, extra_req)
if #remaining_normal == 0 and #remaining_extra == 0 then
break
end
if DispatchCtrl.role_can_help(scored_roles[i].role.tags, remaining_normal, remaining_extra) then
table.insert(test_selected, scored_roles[i].role)
for _, tag in ipairs(scored_roles[i].role.tags) do
table.insert(test_tags, tag)
end
end
end
end
if #test_selected == target_count then
if check_both then
if self:can_meet_requirements(test_tags, normal_req) and self:can_meet_requirements(test_tags, extra_req) then
return test_selected
end
elseif self:can_meet_requirements(test_tags, normal_req) then
return test_selected
end
end
end
end
return nil
end
function DispatchCtrl.role_can_help(role_tags, remaining_normal, remaining_extra)
for _, tag in ipairs(role_tags) do
for _, req in ipairs(remaining_normal) do
if tag == req then
return true
end
end
for _, req in ipairs(remaining_extra) do
if tag == req then
return true
end
end
end
return false
end
function DispatchCtrl:OnEvent_OpenBuildList(dispatchId)
self.bOpenBuild = true
self:RefreshSelectList(true, dispatchId)