Beispiel #1
0
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;
}
Beispiel #2
0
/**
 * 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;
}
Beispiel #3
0
/**
 * 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;
}
Beispiel #4
0
/**
 * 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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
/**
 * 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;
}