/** * 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 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; }