Trying to recreate cargo income using profit callback

Discussions about the technical aspects of graphics development, including NewGRF tools and utilities.

Moderator: Graphics Moderators

Post Reply
User avatar
sevenfm
Engineer
Engineer
Posts: 117
Joined: 25 Jul 2016 23:44
Location: Soviet Russia

Trying to recreate cargo income using profit callback

Post by sevenfm »

Looking at the game code, cargo income is calculated as following:

Code: Select all

	static const int MIN_TIME_FACTOR = 31;
	static const int MAX_TIME_FACTOR = 255;

	const int days1 = cs->transit_days[0];
	const int days2 = cs->transit_days[1];
	const int days_over_days1 = max(   transit_days - days1, 0);
	const int days_over_days2 = max(days_over_days1 - days2, 0);
	
	const int time_factor = max(MAX_TIME_FACTOR - days_over_days1 - days_over_days2, MIN_TIME_FACTOR);

	return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21);
If profit callback is used, then the code is:

Code: Select all

	uint32 var18 = min(dist, 0xFFFF) | (min(num_pieces, 0xFF) << 16) | (transit_days << 24);
		uint16 callback = GetCargoCallback(CBID_CARGO_PROFIT_CALC, 0, var18, cs);
		if (callback != CALLBACK_FAILED) {
			int result = GB(callback, 0, 14);

			/* Simulate a 15 bit signed value */
			if (HasBit(callback, 14)) result -= 0x4000;

			/* "The result should be a signed multiplier that gets multiplied
			 * by the amount of cargo moved and the price factor, then gets
			 * divided by 8192." */
			return result * num_pieces * cs->current_payment / 8192;
		}
Comparing
BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21)
and
result * num_pieces * cs->current_payment / 8192
profit callback should return
result = dist * time_factor / 256

So, I tried to recreate OpenTTD cargo income using profit callback in industry newgrf:

Code: Select all

switch (FEAT_CARGOS, SELF, switch_cargo_profit, 
	[
	// The manhattan distance the cargo was transported.
	STORE_TEMP(getbits(extra_callback_info2, 0, 16), 0),
	// The amount of cargo delivered.
	STORE_TEMP(getbits(extra_callback_info2, 16, 8), 1),
	// The time spent en-route (1 unit = 2.5 days).
	STORE_TEMP(getbits(extra_callback_info2, 24, 8), 2),
 
	// calculate days_over_days1
	STORE_TEMP( max(LOAD_TEMP(2) - 0, 0), 3 ),
 
	// calculate days_over_days2
	STORE_TEMP( max(LOAD_TEMP(3) - 16, 0), 4 ),
 
	// calculate time_factor = max(MAX_TIME_FACTOR - days_over_days1 - days_over_days2, MIN_TIME_FACTOR)
	STORE_TEMP( max(255 - LOAD_TEMP(3) - LOAD_TEMP(4), 31), 5 ),
	new_cargo_income
	]) 
{
	// return dist * time_factor / 256
	1: return LOAD_TEMP(0) * LOAD_TEMP(5) / 256;
	CB_FAILED;
}
Cargo is defined as

Code: Select all

item(FEAT_CARGOS, passengers, 0) {
        property {
            number: 0;
            type_name: TTD_STR_CARGO_PLURAL_PASSENGERS;
            unit_name: TTD_STR_CARGO_SINGULAR_PASSENGER;
            type_abbreviation: TTD_STR_ABBREV_PASSENGERS;
            sprite: NEW_CARGO_SPRITE;
            weight: 0.0625;
            station_list_colour: 152;
            cargo_payment_list_colour: 152;
            is_freight: 0;
            cargo_classes: bitmask(CC_PASSENGERS);
            cargo_label: "PASS";
            town_growth_effect: TOWNGROWTH_PASSENGERS;
            town_growth_multiplier: 1.0;
            units_of_cargo: TTD_STR_PASSENGERS;
            items_of_cargo: TTD_STR_QUANTITY_PASSENGERS;
            penalty_lowerbound: 0;
            single_penalty_length: 16;
            price_factor: 72 * payment_adjust / 100;
            capacity_multiplier: 4;
        }
        graphics {
 	    station_rating: switch_station_rating_pass;
            profit: switch_cargo_profit;
            cargoicon_passengers;
        }
}
I expected same results for cargo profit when using newgrf callback or original game code, but it didn't happen (tested on OpenTTD 1.8).
Cargo income with profit callback is greater by 10-30% depending on distance (checking with same bus, same distance, settings, newgrf set etc), so my attempt failed for some reason.
What am I doing wrong? How to modify my nml code to get identical results?
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 2 guests