static Subsidy *FindSubsidyPassengerRoute() { assert(Subsidy::CanAllocateItem()); const Town *src = Town::GetRandom(); if (src->population < SUBSIDY_PAX_MIN_POPULATION || src->pct_pass_transported > SUBSIDY_MAX_PCT_TRANSPORTED) { return NULL; } const Town *dst = Town::GetRandom(); if (dst->population < SUBSIDY_PAX_MIN_POPULATION || src == dst) { return NULL; } if (DistanceManhattan(src->xy, dst->xy) > SUBSIDY_MAX_DISTANCE) return NULL; if (CheckSubsidyDuplicate(CT_PASSENGERS, ST_TOWN, src->index, ST_TOWN, dst->index)) return NULL; Subsidy *s = new Subsidy(); s->cargo_type = CT_PASSENGERS; s->src_type = s->dst_type = ST_TOWN; s->src = src->index; s->dst = dst->index; return s; }
/** * Tries to create a passenger subsidy between two towns. * @return True iff the subsidy was created. */ bool FindSubsidyPassengerRoute() { if (!Subsidy::CanAllocateItem()) return false; Town *src = Town::GetRandom(); if (src->cache.population < SUBSIDY_PAX_MIN_POPULATION || src->GetPercentTransported(CT_PASSENGERS) > SUBSIDY_MAX_PCT_TRANSPORTED) { return false; } const Town *dst = NULL; if (CargoHasDestinations(CT_PASSENGERS)) { /* Try to get a town from the demand destinations. */ CargoLink *link = src->GetRandomLink(CT_PASSENGERS, false); if (link == src->cargo_links[CT_PASSENGERS].End()) return NULL; if (link->dest != NULL && link->dest->GetType() != ST_TOWN) return NULL; dst = static_cast<const Town *>(link->dest); } if (dst == NULL) dst = Town::GetRandom(); if (dst->cache.population < SUBSIDY_PAX_MIN_POPULATION || src == dst) { return false; } if (DistanceManhattan(src->xy, dst->xy) > SUBSIDY_MAX_DISTANCE) return false; if (CheckSubsidyDuplicate(CT_PASSENGERS, ST_TOWN, src->index, ST_TOWN, dst->index)) return false; CreateSubsidy(CT_PASSENGERS, ST_TOWN, src->index, ST_TOWN, dst->index); return true; }
/** * Tries to find a suitable destination for the given source and cargo. * @param cid Subsidized cargo. * @param src_type Type of \a src. * @param src Index of source. * @return True iff the subsidy was created. */ bool FindSubsidyCargoDestination(CargoID cid, SourceType src_type, SourceID src) { /* Choose a random destination. Only consider towns if they can accept the cargo. */ SourceType dst_type = (HasBit(_town_cargoes_accepted, cid) && Chance16(1, 2)) ? ST_TOWN : ST_INDUSTRY; SourceID dst; switch (dst_type) { case ST_TOWN: { /* Select a random town. */ const Town *dst_town = Town::GetRandom(); /* Check if the town can accept this cargo. */ if (!HasBit(dst_town->cargo_accepted_total, cid)) return false; dst = dst_town->index; break; } case ST_INDUSTRY: { /* Select a random industry. */ const Industry *dst_ind = Industry::GetRandom(); /* The industry must accept the cargo */ if (dst_ind == NULL || (cid != dst_ind->accepts_cargo[0] && cid != dst_ind->accepts_cargo[1] && cid != dst_ind->accepts_cargo[2])) { return false; } dst = dst_ind->index; break; } default: NOT_REACHED(); } /* Check that the source and the destination are not the same. */ if (src_type == dst_type && src == dst) return false; /* Check distance between source and destination. */ if (!CheckSubsidyDistance(src_type, src, dst_type, dst)) return false; /* Avoid duplicate subsidies. */ if (CheckSubsidyDuplicate(cid, src_type, src, dst_type, dst)) return false; CreateSubsidy(cid, src_type, src, dst_type, dst); return true; }
/** * Tries to create a passenger subsidy between two towns. * @return True iff the subsidy was created. */ bool FindSubsidyPassengerRoute() { if (!Subsidy::CanAllocateItem()) return false; const Town *src = Town::GetRandom(); if (src->cache.population < SUBSIDY_PAX_MIN_POPULATION || src->GetPercentTransported(CT_PASSENGERS) > SUBSIDY_MAX_PCT_TRANSPORTED) { return false; } const Town *dst = Town::GetRandom(); if (dst->cache.population < SUBSIDY_PAX_MIN_POPULATION || src == dst) { return false; } if (DistanceManhattan(src->xy, dst->xy) > SUBSIDY_MAX_DISTANCE) return false; if (CheckSubsidyDuplicate(CT_PASSENGERS, ST_TOWN, src->index, ST_TOWN, dst->index)) return false; CreateSubsidy(CT_PASSENGERS, ST_TOWN, src->index, ST_TOWN, dst->index); return true; }
static Subsidy *FindSubsidyCargoRoute() { assert(Subsidy::CanAllocateItem()); const Industry *i = Industry::GetRandom(); if (i == NULL) return NULL; CargoID cargo; int trans, total; /* Randomize cargo type */ if (i->produced_cargo[1] != CT_INVALID && HasBit(Random(), 0)) { cargo = i->produced_cargo[1]; trans = i->last_month_pct_transported[1]; total = i->last_month_production[1]; } else { cargo = i->produced_cargo[0]; trans = i->last_month_pct_transported[0]; total = i->last_month_production[0]; } /* Quit if no production in this industry * or if the pct transported is already large enough */ if (total == 0 || trans > SUBSIDY_MAX_PCT_TRANSPORTED || cargo == CT_INVALID) return NULL; /* Don't allow passengers subsidies from industry */ const CargoSpec *cs = CargoSpec::Get(cargo); if (cs->town_effect == TE_PASSENGERS) return NULL; SourceType dst_type; SourceID dst; if (cs->town_effect == TE_GOODS || cs->town_effect == TE_FOOD) { /* The destination is a town */ dst_type = ST_TOWN; const Town *t = Town::GetRandom(); /* Only want big towns */ if (t->population < SUBSIDY_CARGO_MIN_POPULATION) return NULL; if (DistanceManhattan(i->location.tile, t->xy) > SUBSIDY_MAX_DISTANCE) return NULL; dst = t->index; } else { /* The destination is an industry */ dst_type = ST_INDUSTRY; const Industry *i2 = Industry::GetRandom(); /* The industry must accept the cargo */ if (i2 == NULL || i == i2 || (cargo != i2->accepts_cargo[0] && cargo != i2->accepts_cargo[1] && cargo != i2->accepts_cargo[2])) { return NULL; } if (DistanceManhattan(i->location.tile, i2->location.tile) > SUBSIDY_MAX_DISTANCE) return NULL; dst = i2->index; } if (CheckSubsidyDuplicate(cargo, ST_INDUSTRY, i->index, dst_type, dst)) return NULL; Subsidy *s = new Subsidy(); s->cargo_type = cargo; s->src_type = ST_INDUSTRY; s->src = i->index; s->dst_type = dst_type; s->dst = dst; return s; }
/** * Tries to find a suitable destination for the given source and cargo. * @param cid Subsidized cargo. * @param src_type Type of \a src. * @param src Index of source. * @return True iff the subsidy was created. */ bool FindSubsidyCargoDestination(CargoID cid, SourceType src_type, SourceID src) { /* Choose a random destination. Only consider towns if they can accept the cargo. */ SourceType dst_type = (HasBit(_town_cargoes_accepted, cid) && Chance16(1, 2)) ? ST_TOWN : ST_INDUSTRY; CargoSourceSink *src_sink = (src_type == ST_TOWN) ? (CargoSourceSink *) Town::Get(src) : (CargoSourceSink *) Industry::Get(src); SourceID dst; switch (dst_type) { case ST_TOWN: { /* Select a random town. */ const Town *dst_town = NULL; if (CargoHasDestinations(cid)) { /* Try to get a town from the demand destinations. */ CargoLink *link = src_sink->GetRandomLink(cid, false); if (link == src_sink->cargo_links[cid].End()) return NULL; if (link->dest != NULL && link->dest->GetType() != dst_type) return NULL; dst_town = static_cast<const Town *>(link->dest); } if (dst_town == NULL) dst_town = Town::GetRandom(); /* Check if the town can accept this cargo. */ if (!HasBit(dst_town->cargo_accepted_total, cid)) return false; dst = dst_town->index; break; } case ST_INDUSTRY: { /* Select a random industry. */ const Industry *dst_ind = Industry::GetRandom(); if (CargoHasDestinations(cid)) { /* Try to get a town from the demand destinations. */ CargoLink *link = src_sink->GetRandomLink(cid, false); if (link == src_sink->cargo_links[cid].End()) return NULL; if (link->dest != NULL && link->dest->GetType() != dst_type) return NULL; dst_ind = static_cast<const Industry *>(link->dest); } if (dst_ind == NULL) dst_ind = Industry::GetRandom(); dst = dst_ind->index; /* The industry must accept the cargo */ if (dst_ind == NULL || (src_type == dst_type && src == dst) || (cid != dst_ind->accepts_cargo[0] && cid != dst_ind->accepts_cargo[1] && cid != dst_ind->accepts_cargo[2])) { return false; } break; } default: NOT_REACHED(); } /* Check that the source and the destination are not the same. */ if (src_type == dst_type && src == dst) return false; /* Check distance between source and destination. */ if (!CheckSubsidyDistance(src_type, src, dst_type, dst)) return false; /* Avoid duplicate subsidies. */ if (CheckSubsidyDuplicate(cid, src_type, src, dst_type, dst)) return false; CreateSubsidy(cid, src_type, src, dst_type, dst); return true; }