Add: Cargo delivery monitoring and updating.
This commit is contained in:
83
company.nut
83
company.nut
@@ -2,24 +2,57 @@
|
|||||||
|
|
||||||
// A goal for a company.
|
// A goal for a company.
|
||||||
class CompanyGoal {
|
class CompanyGoal {
|
||||||
cid = null;
|
cargo_id = null; // Cargo id
|
||||||
accept = null;
|
accept = null; // Accepting resource.
|
||||||
wanted_amount = null;
|
wanted_amount = null; // Amount to deliver for achieving the goal.
|
||||||
|
delivered_amount = 0; // Amount delivered so far.
|
||||||
|
|
||||||
constructor(cid, accept, wanted_amount) {
|
constructor(cargo_id, accept, wanted_amount) {
|
||||||
this.cid = cid;
|
this.cargo_id = cargo_id;
|
||||||
this.accept = accept;
|
this.accept = accept;
|
||||||
this.wanted_amount = wanted_amount;
|
this.wanted_amount = wanted_amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AddMonitorElement(mon);
|
||||||
|
function UpdateDelivered(mon);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Add an entry to the collection of monitored things.
|
||||||
|
// @param [inout] mon Table with 'cargo_id' to 'town' and 'ind' tables, holding ids to 'null'.
|
||||||
|
function CompanyGoal::AddMonitorElement(mon)
|
||||||
|
{
|
||||||
|
if (!(this.cargo_id in mon)) mon[this.cargo_id] <- {};
|
||||||
|
mon = mon[this.cargo_id];
|
||||||
|
if ("ind" in this.accept) {
|
||||||
|
if (!("ind" in mon)) mon.ind <- {};
|
||||||
|
mon.ind[this.accept.ind] <- null;
|
||||||
|
} else {
|
||||||
|
if (!("town" in mon)) mon.town <- {};
|
||||||
|
mon.town[this.accept.town] <- null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the delivered amount from the monitored amounts.
|
||||||
|
function CompanyGoal::UpdateDelivered(mon)
|
||||||
|
{
|
||||||
|
local delivered;
|
||||||
|
if ("ind" in this.accept) {
|
||||||
|
delivered = mon[this.cargo_id].ind[this.accept.ind];
|
||||||
|
} else {
|
||||||
|
delivered = mon[this.cargo_id].town[this.accept.town];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.delivered_amount += delivered;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class CompanyData {
|
class CompanyData {
|
||||||
cid = null;
|
comp_id = null;
|
||||||
|
|
||||||
active_goals = {};
|
active_goals = {};
|
||||||
|
|
||||||
constructor(cid) {
|
constructor(comp_id) {
|
||||||
this.cid = cid;
|
this.comp_id = comp_id;
|
||||||
|
|
||||||
for (local num = 0; num < 5; num += 1) this.active_goals[num] <- null;
|
for (local num = 0; num < 5; num += 1) this.active_goals[num] <- null;
|
||||||
}
|
}
|
||||||
@@ -27,6 +60,9 @@ class CompanyData {
|
|||||||
function GetMissingGoalCount();
|
function GetMissingGoalCount();
|
||||||
function AddActiveGoal(cargo_id, accept, amount);
|
function AddActiveGoal(cargo_id, accept, amount);
|
||||||
function HasGoal(cargo_id, accept);
|
function HasGoal(cargo_id, accept);
|
||||||
|
|
||||||
|
function AddMonitorElement(mon);
|
||||||
|
function UpdateDelivered(mon);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Find the number of active goals that are missing for this company.
|
// Find the number of active goals that are missing for this company.
|
||||||
@@ -62,7 +98,7 @@ function CompanyData::HasGoal(cargo_id, accept)
|
|||||||
{
|
{
|
||||||
foreach (num, goal in this.active_goals) {
|
foreach (num, goal in this.active_goals) {
|
||||||
if (goal == null) continue;
|
if (goal == null) continue;
|
||||||
if (goal.cid != cargo_id) continue;
|
if (goal.cargo_id != cargo_id) continue;
|
||||||
if ("town" in accept) {
|
if ("town" in accept) {
|
||||||
if ("ind" in goal.accept || accept.town != goal.accept.town) continue;
|
if ("ind" in goal.accept || accept.town != goal.accept.town) continue;
|
||||||
} else {
|
} else {
|
||||||
@@ -72,3 +108,32 @@ function CompanyData::HasGoal(cargo_id, accept)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add monitor elements of a company, if they exist.
|
||||||
|
// @param [inout] cmon Monitors of all companies, updated in-place.
|
||||||
|
// Result is 'comp_id' number to 'cargo_id' numbers to 'ind' and/or 'town' indices to 'null'
|
||||||
|
function CompanyData::AddMonitorElements(cmon)
|
||||||
|
{
|
||||||
|
local mon = {};
|
||||||
|
foreach (num, goal in this.active_goals) {
|
||||||
|
if (goal == null) continue;
|
||||||
|
goal.AddMonitorElement(mon);
|
||||||
|
}
|
||||||
|
if (mon.len() == 0) return;
|
||||||
|
|
||||||
|
cmon[this.comp_id] <- mon;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Distribute the delivered amounts to the goals.
|
||||||
|
// @param cmon Monitor results of all companies, 'comp_id' numbers to 'cargo_id' number to
|
||||||
|
// 'ind' and/or 'town' to resource indices to amount.
|
||||||
|
function CompanyData::UpdateDelivereds(cmon)
|
||||||
|
{
|
||||||
|
if (this.comp_id in cmon) {
|
||||||
|
foreach (num, goal in this.active_goals) {
|
||||||
|
if (goal == null) continue;
|
||||||
|
goal.UpdateDelivered(cmon[this.comp_id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
137
main.nut
137
main.nut
@@ -220,6 +220,8 @@ function FMainClass::Start()
|
|||||||
// Main event loop.
|
// Main event loop.
|
||||||
local companies_timeout = 0;
|
local companies_timeout = 0;
|
||||||
local goal_timeout = 0;
|
local goal_timeout = 0;
|
||||||
|
local monitor_timeout = 0;
|
||||||
|
local old_cmonitor = null;
|
||||||
while (true) {
|
while (true) {
|
||||||
// Check for new or disappeared companies.
|
// Check for new or disappeared companies.
|
||||||
if (companies_timeout <= 0) {
|
if (companies_timeout <= 0) {
|
||||||
@@ -227,6 +229,7 @@ function FMainClass::Start()
|
|||||||
if (GSCompany.ResolveCompanyID(cid) == GSCompany.COMPANY_INVALID) {
|
if (GSCompany.ResolveCompanyID(cid) == GSCompany.COMPANY_INVALID) {
|
||||||
if (this.companies[cid] != null) {
|
if (this.companies[cid] != null) {
|
||||||
// XXX Handle company disappearing
|
// XXX Handle company disappearing
|
||||||
|
monitor_timeout = 0; // Force updating of the goals.
|
||||||
GSLog.Info("Deleted company " + cid);
|
GSLog.Info("Deleted company " + cid);
|
||||||
}
|
}
|
||||||
this.companies[cid] = null;
|
this.companies[cid] = null;
|
||||||
@@ -256,7 +259,10 @@ function FMainClass::Start()
|
|||||||
cid_missing = missing;
|
cid_missing = missing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (best_cid != null) this.CreateChallenge(best_cid);
|
if (best_cid != null) {
|
||||||
|
this.CreateChallenge(best_cid);
|
||||||
|
monitor_timeout = 0; // Force updating of the monitor.
|
||||||
|
}
|
||||||
|
|
||||||
if (total_missing > 1) {
|
if (total_missing > 1) {
|
||||||
goal_timeout = 1 * 74; // If more missing goals, wait only a short while.
|
goal_timeout = 1 * 74; // If more missing goals, wait only a short while.
|
||||||
@@ -265,6 +271,34 @@ function FMainClass::Start()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Monitoring and updating of company goals. Note that code above may force an update.
|
||||||
|
if (monitor_timeout <= 0) {
|
||||||
|
local cmon = {};
|
||||||
|
// Collect monitors that are of interest.
|
||||||
|
foreach (cid, cdata in companies) {
|
||||||
|
if (cdata == null) continue;
|
||||||
|
cdata.AddMonitorElements(cmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_cmonitor == null) { // First run, clear any old monitoring.
|
||||||
|
GSCargoMonitor.StopAllMonitoring();
|
||||||
|
old_cmonitor = {};
|
||||||
|
}
|
||||||
|
this.FillMonitors(cmon); // Query the monitors.
|
||||||
|
|
||||||
|
// Distribute the retrieved data.
|
||||||
|
foreach (cid, cdata in companies) {
|
||||||
|
if (cdata == null) continue;
|
||||||
|
cdata.UpdateDelivereds(cmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop obsolete monitors.
|
||||||
|
this.UpdateCompanyMonitors(old_cmonitor, cmon);
|
||||||
|
old_cmonitor = cmon;
|
||||||
|
|
||||||
|
monitor_timeout = 15 * 74; // By default, check monitors every 15 days (other processes may force a check earlier).
|
||||||
|
}
|
||||||
|
|
||||||
// local lake_news = GSText(GSText.STR_LAKE_NEWS);
|
// local lake_news = GSText(GSText.STR_LAKE_NEWS);
|
||||||
// GSNews.Create(GSNews.NT_GENERAL, lake_news, GSCompany.COMPANY_INVALID);
|
// GSNews.Create(GSNews.NT_GENERAL, lake_news, GSCompany.COMPANY_INVALID);
|
||||||
// GSGoal.Question(1, GSCompany.COMPANY_INVALID, lake_news, GSGoal.QT_INFORMATION, GSGoal.BUTTON_GO);
|
// GSGoal.Question(1, GSCompany.COMPANY_INVALID, lake_news, GSGoal.QT_INFORMATION, GSGoal.BUTTON_GO);
|
||||||
@@ -272,12 +306,109 @@ function FMainClass::Start()
|
|||||||
// Sleep until the next event.
|
// Sleep until the next event.
|
||||||
local delay_time = 5000;
|
local delay_time = 5000;
|
||||||
if (delay_time > companies_timeout) delay_time = companies_timeout;
|
if (delay_time > companies_timeout) delay_time = companies_timeout;
|
||||||
if (delay_time > goal_timeout) delay_time = goal_timeout;
|
if (delay_time > goal_timeout) delay_time = goal_timeout;
|
||||||
|
if (delay_time > monitor_timeout) delay_time = monitor_timeout;
|
||||||
|
|
||||||
// XXX Perhaps check for company events?
|
// XXX Perhaps check for company events?
|
||||||
if (delay_time > 0) this.Sleep(delay_time);
|
if (delay_time > 0) this.Sleep(delay_time);
|
||||||
|
|
||||||
companies_timeout -= delay_time;
|
companies_timeout -= delay_time;
|
||||||
goal_timeout -= delay_time;
|
goal_timeout -= delay_time;
|
||||||
|
monitor_timeout -= delay_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill company monitors with monitored amounts.
|
||||||
|
// @param [inout] cmon Table of 'comp_id' number to 'cargo_id' number to
|
||||||
|
// 'ind' and/or 'town' to resource indices to 'null'.
|
||||||
|
function FMainClass::FillMonitors(cmon)
|
||||||
|
{
|
||||||
|
foreach (comp_id, mon in cmon) {
|
||||||
|
foreach (cargo_id, rmon in mon) {
|
||||||
|
if ("ind" in rmon) {
|
||||||
|
foreach (ind_id, _ in rmon.ind) {
|
||||||
|
local amount = GSCargoMonitor.GetIndustryDeliveryAmount(comp_id, cargo_id, ind_id, true);
|
||||||
|
rmon.ind[ind_id] = amount;
|
||||||
|
local text = "Industry " + GSIndustry.GetName(ind_id) + " received " + amount +
|
||||||
|
" units for company " + comp_id +
|
||||||
|
", cargo " + GSCargo.GetCargoLabel(cargo_id);
|
||||||
|
GSLog.Info(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ("town" in rmon) {
|
||||||
|
foreach (town_id, _ in rmon.town) {
|
||||||
|
local amount = GSCargoMonitor.GetTownDeliveryAmount(comp_id, cargo_id, town_id, true);
|
||||||
|
rmon.town[town_id] = amount;
|
||||||
|
local text = "Town " + GSTown.GetName(town_id) + " received " + amount +
|
||||||
|
" units for company " + comp_id +
|
||||||
|
", cargo " + GSCargo.GetCargoLabel(cargo_id);
|
||||||
|
GSLog.Info(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function FMainClass::UpdateCompanyMonitors(old_cmon, cmon)
|
||||||
|
{
|
||||||
|
foreach (comp_id, old_mon in old_cmon) {
|
||||||
|
if (comp_id in cmon) {
|
||||||
|
this.UpdateCargoMonitors(comp_id, old_mon, cmon[comp_id]);
|
||||||
|
} else {
|
||||||
|
this.UpdateCargoMonitors(comp_id, old_mon, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function FMainClass::UpdateCargoMonitors(comp_id, old_mon, mon)
|
||||||
|
{
|
||||||
|
foreach (cargo_id, old_rmon in old_mon) {
|
||||||
|
if (cargo_id in mon) {
|
||||||
|
this.UpdateResourceMonitors(comp_id, cargo_id, old_rmon, mon[cargo_id]);
|
||||||
|
} else {
|
||||||
|
this.UpdateResourceMonitors(comp_id, cargo_id, old_rmon, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function FMainClass::UpdateResourceMonitors(comp_id, cargo_id, old_rmon, rmon)
|
||||||
|
{
|
||||||
|
if ("town" in old_rmon) {
|
||||||
|
if ("town" in rmon) {
|
||||||
|
this.UpdateTownMonitors(comp_id, cargo_id, old_rmon.town, rmon.town);
|
||||||
|
} else {
|
||||||
|
this.UpdateTownMonitors(comp_id, cargo_id, old_rmon.town, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ("ind" in old_rmon) {
|
||||||
|
if ("ind" in rmon) {
|
||||||
|
this.UpdateIndMonitors(comp_id, cargo_id, old_rmon.ind, rmon.ind);
|
||||||
|
} else {
|
||||||
|
this.UpdateIndMonitors(comp_id, cargo_id, old_rmon.ind, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function FMainClass::UpdateTownMonitors(comp_id, cargo_id, old_tmon, tmon)
|
||||||
|
{
|
||||||
|
foreach (town_id, _ in old_tmon) {
|
||||||
|
if (!(town_id in tmon)) {
|
||||||
|
GSCargoMonitor.GetTownDeliveryAmount(comp_id, cargo_id, town_id, false);
|
||||||
|
local text = "Stop monitoring town " + GSTown.GetName(town_id) +
|
||||||
|
"for company " + comp_id + ", cargo " + GSCargo.GetCargoLabel(cargo_id);
|
||||||
|
GSLog.Info(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function FMainClass::UpdateIndMonitors(comp_id, cargo_id, old_imon, imon)
|
||||||
|
{
|
||||||
|
foreach (ind_id, _ in old_imon) {
|
||||||
|
if (!(ind_id in imon)) {
|
||||||
|
GSCargoMonitor.GetIndustryDeliveryAmount(comp_id, cargo_id, ind_id, false);
|
||||||
|
local text = "Stop monitoring industry " + GSIndustry.GetName(ind_id) +
|
||||||
|
"for company " + comp_id + ", cargo " + GSCargo.GetCargoLabel(cargo_id);
|
||||||
|
GSLog.Info(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user