/** * 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; }
/** * Create a new subsidy. * @param tile unused. * @param flags type of operation * @param p1 various bitstuffed elements * - p1 = (bit 0 - 7) - SourceType of source. * - p1 = (bit 8 - 23) - SourceID of source. * - p1 = (bit 24 - 31) - CargoID of subsidy. * @param p2 various bitstuffed elements * - p2 = (bit 0 - 7) - SourceType of destination. * - p2 = (bit 8 - 23) - SourceID of destination. * @param text unused. * @return the cost of this operation or an error */ CommandCost CmdCreateSubsidy(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { if (!Subsidy::CanAllocateItem()) return CMD_ERROR; CargoID cid = GB(p1, 24, 8); SourceType src_type = (SourceType)GB(p1, 0, 8); SourceID src = GB(p1, 8, 16); SourceType dst_type = (SourceType)GB(p2, 0, 8); SourceID dst = GB(p2, 8, 16); if (_current_company != OWNER_DEITY) return CMD_ERROR; if (cid >= NUM_CARGO || !::CargoSpec::Get(cid)->IsValid()) return CMD_ERROR; switch (src_type) { case ST_TOWN: if (!Town::IsValidID(src)) return CMD_ERROR; break; case ST_INDUSTRY: if (!Industry::IsValidID(src)) return CMD_ERROR; break; default: return CMD_ERROR; } switch (dst_type) { case ST_TOWN: if (!Town::IsValidID(dst)) return CMD_ERROR; break; case ST_INDUSTRY: if (!Industry::IsValidID(dst)) return CMD_ERROR; break; default: return CMD_ERROR; } if (flags & DC_EXEC) { CreateSubsidy(cid, src_type, src, dst_type, dst); } return CommandCost(); }
/** * 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; }
/** * 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; }