Changeset - r13039:b4bc7fb3d664
[Not reviewed]
master
0 2 0
rubidium - 15 years ago 2009-09-15 17:24:18
rubidium@openttd.org
(svn r17547) -Feature: [NewGRF] Implement callback 145 (custom station rating)
2 files changed with 45 insertions and 27 deletions:
0 comments (0 inline, 0 general)
src/newgrf_callbacks.h
Show inline comments
 
@@ -189,13 +189,13 @@ enum CallbackID {
 
	CBID_HOUSE_DENY_DESTRUCTION          = 0x143, // 15 bit callback
 

	
 
	/** Select an ambient sound to play for a given type of tile. */
 
	CBID_SOUNDS_AMBIENT_EFFECT           = 0x144, // 15 bit callback, not implemented
 

	
 
	/** Called to calculate part of a station rating. */
 
	CBID_CARGO_STATION_RATING_CALC       = 0x145, // 15 bit callback, not implemented
 
	CBID_CARGO_STATION_RATING_CALC       = 0x145, // 15 bit callback
 

	
 
	/** Allow signal sprites to be replaced dynamically. */
 
	CBID_NEW_SIGNALS_SPRITE_DRAW         = 0x146, // 15 bit callback, not implemented
 

	
 
	/** Add an offset to the default sprite numbers to show another sprite. */
 
	CBID_CANALS_SPRITE_OFFSET            = 0x147, // 15 bit callback, not implemented
src/station_cmd.cpp
Show inline comments
 
@@ -2724,60 +2724,78 @@ static void UpdateStationRating(Station 
 
{
 
	bool waiting_changed = false;
 

	
 
	byte_inc_sat(&st->time_since_load);
 
	byte_inc_sat(&st->time_since_unload);
 

	
 
	GoodsEntry *ge = st->goods;
 
	do {
 
	const CargoSpec *cs;
 
	FOR_ALL_CARGOSPECS(cs) {
 
		GoodsEntry *ge = &st->goods[cs->Index()];
 
		/* Slowly increase the rating back to his original level in the case we
 
		 *  didn't deliver cargo yet to this station. This happens when a bribe
 
		 *  failed while you didn't moved that cargo yet to a station. */
 
		if (!HasBit(ge->acceptance_pickup, GoodsEntry::PICKUP) && ge->rating < INITIAL_STATION_RATING) {
 
			ge->rating++;
 
		}
 

	
 
		/* Only change the rating if we are moving this cargo */
 
		if (HasBit(ge->acceptance_pickup, GoodsEntry::PICKUP)) {
 
			byte_inc_sat(&ge->days_since_pickup);
 

	
 
			bool skip = false;
 
			int rating = 0;
 

	
 
			{
 
				int b = ge->last_speed - 85;
 
				if (b >= 0)
 
					rating += b >> 2;
 
			uint waiting = ge->cargo.Count();
 

	
 
			if (HasBit(cs->callback_mask, CBM_CARGO_STATION_RATING_CALC)) {
 
				/* Perform custom station rating. If it succeeds the speed, days in transit and
 
				 * waiting cargo ratings must not be executed. */
 

	
 
				/* NewGRFs expect last speed to be 0xFF when no vehicle has arrived yet. */
 
				uint last_speed = ge->last_speed;
 
				if (last_speed == 0) last_speed = 0xFF;
 

	
 
				uint32 var18 = min(ge->days_since_pickup, 0xFF) | (min(waiting, 0xFFFF) << 8) | (min(last_speed, 0xFF) << 24);
 
				/* Convert to the 'old' vehicle types */
 
				uint32 var10 = (st->last_vehicle_type == VEH_INVALID) ? 0x0 : (st->last_vehicle_type + 0x10);
 
				uint16 callback = GetCargoCallback(CBID_CARGO_STATION_RATING_CALC, var10, var18, cs);
 
				if (callback != CALLBACK_FAILED) {
 
					skip = true;
 
					rating = GB(callback, 0, 14);
 

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

	
 
			{
 
				byte age = ge->last_age;
 
				(age >= 3) ||
 
				(rating += 10, age >= 2) ||
 
				(rating += 10, age >= 1) ||
 
				(rating += 13, true);
 
			}
 

	
 
			if (Company::IsValidID(st->owner) && HasBit(st->town->statues, st->owner)) rating += 26;
 

	
 
			{
 
			if (!skip) {
 
				int b = ge->last_speed - 85;
 
				if (b >= 0) rating += b >> 2;
 

	
 
				byte days = ge->days_since_pickup;
 
				if (st->last_vehicle_type == VEH_SHIP) days >>= 2;
 
				(days > 21) ||
 
				(rating += 25, days > 12) ||
 
				(rating += 25, days > 6) ||
 
				(rating += 45, days > 3) ||
 
				(rating += 35, true);
 

	
 
				(rating -= 90, waiting > 1500) ||
 
				(rating += 55, waiting > 1000) ||
 
				(rating += 35, waiting > 600) ||
 
				(rating += 10, waiting > 300) ||
 
				(rating += 20, waiting > 100) ||
 
				(rating += 10, true);
 
			}
 

	
 
			uint waiting = ge->cargo.Count();
 
			(rating -= 90, waiting > 1500) ||
 
			(rating += 55, waiting > 1000) ||
 
			(rating += 35, waiting > 600) ||
 
			(rating += 10, waiting > 300) ||
 
			(rating += 20, waiting > 100) ||
 
			(rating += 10, true);
 
			if (Company::IsValidID(st->owner) && HasBit(st->town->statues, st->owner)) rating += 26;
 

	
 
			byte age = ge->last_age;
 
			(age >= 3) ||
 
			(rating += 10, age >= 2) ||
 
			(rating += 10, age >= 1) ||
 
			(rating += 13, true);
 

	
 
			{
 
				int or_ = ge->rating; // old rating
 

	
 
				/* only modify rating in steps of -2, -1, 0, 1 or 2 */
 
				ge->rating = rating = or_ + Clamp(Clamp(rating, 0, 255) - or_, -2, 2);
 
@@ -2816,13 +2834,13 @@ static void UpdateStationRating(Station 
 
					waiting_changed = true;
 
				}
 

	
 
				if (waiting_changed) ge->cargo.Truncate(waiting);
 
			}
 
		}
 
	} while (++ge != endof(st->goods));
 
	}
 

	
 
	StationID index = st->index;
 
	if (waiting_changed) {
 
		SetWindowDirty(WC_STATION_VIEW, index); // update whole window
 
	} else {
 
		SetWindowWidgetDirty(WC_STATION_VIEW, index, SVW_RATINGLIST); // update only ratings list
0 comments (0 inline, 0 general)