Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
/**
 * 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();
}
Ejemplo n.º 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;
}
Ejemplo n.º 5
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;
}