Fix: Prevent duplicate cargo/resource combinations for a company.

This commit is contained in:
Alberth
2014-12-28 17:22:54 +01:00
parent 744419dd92
commit 2e13920e38
2 changed files with 33 additions and 3 deletions

View File

@@ -13,8 +13,11 @@ class CompanyData {
function GetMissingGoalCount(); function GetMissingGoalCount();
function AddActiveGoal(cargo_id, accept, amount); function AddActiveGoal(cargo_id, accept, amount);
function HasGoal(cargo_id, accept);
}; };
// Find the number of active goals that are missing for this company.
// @return Number of additional goals that the company needs.
function CompanyData::GetMissingGoalCount() function CompanyData::GetMissingGoalCount()
{ {
local missing = 0; local missing = 0;
@@ -24,6 +27,10 @@ function CompanyData::GetMissingGoalCount()
return missing; return missing;
} }
// Add a goal to the list of the company.
// @param cargo_id Cargo of the goal.
// @param accept Accepting resource of the goal.
// @param amount Amount of cargo to deliver.
function CompanyData::AddActiveGoal(cargo_id, accept, amount) function CompanyData::AddActiveGoal(cargo_id, accept, amount)
{ {
foreach (num, goal in this.active_goals) { foreach (num, goal in this.active_goals) {
@@ -33,3 +40,22 @@ function CompanyData::AddActiveGoal(cargo_id, accept, amount)
} }
} }
} }
// Does the company have an active goal for the given cargo and accepting resource?
// @param cargo_id Cargo to check for.
// @param accept Accepting resource to check.
// @return Whether the company has a goal for the cargo and resource.
function CompanyData::HasGoal(cargo_id, accept)
{
foreach (num, goal in this.active_goals) {
if (goal == null) continue;
if (goal.cid != cargo_id) continue;
if ("town" in accept) {
if ("ind" in goal.accept || accept.town != goal.accept.town) continue;
} else {
if ("town" in goal.accept || accept.ind != goal.accept.ind) continue;
}
return true;
}
return false;
}

View File

@@ -115,16 +115,19 @@ function FMainClass::GetDistanceScore(desired, actual)
// Try to find a challenge for a given cargo and a desired distance. // Try to find a challenge for a given cargo and a desired distance.
// @param cargo Cargo entry from FMainClass.cargoes (table with 'cid', 'freight', 'effect'). // @param cargo Cargo entry from FMainClass.cargoes (table with 'cid', 'freight', 'effect').
// @param distance Desired distance between source and target. // @param distance Desired distance between source and target.
// @param company Company to find a challenge for. // @param cid Company to find a challenge for.
// @return Best accepting industry to use, or 'null' if no industry-pair found. // @return Best accepting industry to use, or 'null' if no industry-pair found.
function FMainClass::FindChallenge(cargo_id, distance, company) function FMainClass::FindChallenge(cargo_id, distance, cid)
{ {
local prods = this.FindSources(cargo_id); local prods = this.FindSources(cargo_id);
local accepts = this.FindDestinations(cargo_id, company); local accepts = this.FindDestinations(cargo_id, cid);
local cdata = this.companies[cid];
local best_score = 0; // Best overall distance. local best_score = 0; // Best overall distance.
local best_accept = null; // Best accepting to target. local best_accept = null; // Best accepting to target.
foreach (_, accept in accepts) { foreach (_, accept in accepts) {
if (cdata != null && cdata.HasGoal(cargo_id, accept)) continue; // Prevent duplicates.
local min_prod_distance = distance * 2; // Smallest found distance to the accepting industry. local min_prod_distance = distance * 2; // Smallest found distance to the accepting industry.
local prod_score = GetDistanceScore(distance, min_prod_distance); local prod_score = GetDistanceScore(distance, min_prod_distance);
foreach (_, prod in prods) { foreach (_, prod in prods) {
@@ -165,6 +168,7 @@ function FMainClass::CreateChallenge(cid)
} }
if (cdata != null) { if (cdata != null) {
cdata.AddActiveGoal(cargo, accept, amount); cdata.AddActiveGoal(cargo, accept, amount);
local destination_name = "foo"; local destination_name = "foo";
local destination_string = "foo"; local destination_string = "foo";
if ("town" in accept) { if ("town" in accept) {