コード例 #1
0
ファイル: subsidy.cpp プロジェクト: ComLock/OpenTTD
/**
 * 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;
}
コード例 #2
0
ファイル: subsidy.cpp プロジェクト: andrew889/OpenTTD
void SubsidyMonthlyLoop()
{
	bool modified = false;

	Subsidy *s;
	FOR_ALL_SUBSIDIES(s) {
		if (--s->remaining == 0) {
			if (!s->IsAwarded()) {
				Pair reftype = SetupSubsidyDecodeParam(s, 1);
				AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst);
				AI::BroadcastNewEvent(new AIEventSubsidyOfferExpired(s->index));
			} else {
				if (s->awarded == _local_company) {
					Pair reftype = SetupSubsidyDecodeParam(s, 1);
					AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst);
				}
				AI::BroadcastNewEvent(new AIEventSubsidyExpired(s->index));
			}
			delete s;
			modified = true;
		}
	}

	if (modified) RebuildSubsidisedSourceAndDestinationCache();

	/* 25% chance to go on */
	if (Subsidy::CanAllocateItem() && Chance16(1, 4)) {
		uint n = 1000;
		do {
			Subsidy *s = FindSubsidyPassengerRoute();
			if (s == NULL) s = FindSubsidyCargoRoute();
			if (s != NULL) {
				s->remaining = SUBSIDY_OFFER_MONTHS;
				s->awarded = INVALID_COMPANY;
				Pair reftype = SetupSubsidyDecodeParam(s, 0);
				AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst);
				SetPartOfSubsidyFlag(s->src_type, s->src, POS_SRC);
				SetPartOfSubsidyFlag(s->dst_type, s->dst, POS_DST);
				AI::BroadcastNewEvent(new AIEventSubsidyOffer(s->index));
				modified = true;
				break;
			}
		} while (n--);
	}

	if (modified) InvalidateWindowData(WC_SUBSIDIES_LIST, 0);
}
コード例 #3
0
ファイル: subsidy.cpp プロジェクト: koreapyj/openttd-yapp
/**
 * 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;
}