src/engine.cpp
branchgamebalance
changeset 9911 0b8b245a2391
parent 9910 0b2aebc8283e
child 9912 1ac8aac92385
equal deleted inserted replaced
9910:0b2aebc8283e 9911:0b8b245a2391
    18 #include "train.h"
    18 #include "train.h"
    19 #include "aircraft.h"
    19 #include "aircraft.h"
    20 #include "newgrf_cargo.h"
    20 #include "newgrf_cargo.h"
    21 #include "date.h"
    21 #include "date.h"
    22 #include "table/engines.h"
    22 #include "table/engines.h"
       
    23 #include "group.h"
    23 
    24 
    24 EngineInfo _engine_info[TOTAL_NUM_ENGINES];
    25 EngineInfo _engine_info[TOTAL_NUM_ENGINES];
    25 RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES];
    26 RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES];
    26 ShipVehicleInfo _ship_vehicle_info[NUM_SHIP_ENGINES];
    27 ShipVehicleInfo _ship_vehicle_info[NUM_SHIP_ENGINES];
    27 AircraftVehicleInfo _aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES];
    28 AircraftVehicleInfo _aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES];
    67 
    68 
    68 
    69 
    69 static void CalcEngineReliability(Engine *e)
    70 static void CalcEngineReliability(Engine *e)
    70 {
    71 {
    71 	uint age = e->age;
    72 	uint age = e->age;
       
    73 
       
    74 	/* Check for early retirement */
       
    75 	if (e->player_avail != 0 && !_patches.never_expire_vehicles) {
       
    76 		uint retire_early = EngInfo(e - _engines)->retire_early;
       
    77 		if (retire_early > 0 && age >= e->duration_phase_1 + e->duration_phase_2 - retire_early * 12) {
       
    78 			/* Early retirement is enabled and we're past the date... */
       
    79 			e->player_avail = 0;
       
    80 			AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type);
       
    81 		}
       
    82 	}
    72 
    83 
    73 	if (age < e->duration_phase_1) {
    84 	if (age < e->duration_phase_1) {
    74 		uint start = e->reliability_start;
    85 		uint start = e->reliability_start;
    75 		e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start;
    86 		e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start;
    76 	} else if ((age -= e->duration_phase_1) < e->duration_phase_2 || _patches.never_expire_vehicles) {
    87 	} else if ((age -= e->duration_phase_1) < e->duration_phase_2 || _patches.never_expire_vehicles) {
   399 	if (e->type != type) return false;
   410 	if (e->type != type) return false;
   400 
   411 
   401 	/* check if it's available */
   412 	/* check if it's available */
   402 	if (!HASBIT(e->player_avail, player)) return false;
   413 	if (!HASBIT(e->player_avail, player)) return false;
   403 
   414 
       
   415 	if (type == VEH_TRAIN) {
       
   416 		/* Check if the rail type is available to this player */
       
   417 		const Player *p = GetPlayer(player);
       
   418 		if (!HASBIT(p->avail_railtypes, RailVehInfo(engine)->railtype)) return false;
       
   419 	}
       
   420 
   404 	return true;
   421 	return true;
   405 }
   422 }
   406 
   423 
   407 /** Get the default cargo type for a certain engine type
   424 /** Get the default cargo type for a certain engine type
   408  * @param engine The ID to get the cargo for
   425  * @param engine The ID to get the cargo for
   463 	for (er = GetEngineRenew(0); er != NULL; er = (er->index + 1U < GetEngineRenewPoolSize()) ? GetEngineRenew(er->index + 1U) : NULL) {
   480 	for (er = GetEngineRenew(0); er != NULL; er = (er->index + 1U < GetEngineRenewPoolSize()) ? GetEngineRenew(er->index + 1U) : NULL) {
   464 		if (IsValidEngineRenew(er)) continue;
   481 		if (IsValidEngineRenew(er)) continue;
   465 
   482 
   466 		er->to = INVALID_ENGINE;
   483 		er->to = INVALID_ENGINE;
   467 		er->next = NULL;
   484 		er->next = NULL;
       
   485 		er->group_id = DEFAULT_GROUP;
   468 		return er;
   486 		return er;
   469 	}
   487 	}
   470 
   488 
   471 	/* Check if we can add a block to the pool */
   489 	/* Check if we can add a block to the pool */
   472 	if (AddBlockToPool(&_EngineRenew_pool)) return AllocateEngineRenew();
   490 	if (AddBlockToPool(&_EngineRenew_pool)) return AllocateEngineRenew();
   475 }
   493 }
   476 
   494 
   477 /**
   495 /**
   478  * Retrieves the EngineRenew that specifies the replacement of the given
   496  * Retrieves the EngineRenew that specifies the replacement of the given
   479  * engine type from the given renewlist */
   497  * engine type from the given renewlist */
   480 static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine)
   498 static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine, GroupID group)
   481 {
   499 {
   482 	EngineRenew *er = (EngineRenew *)erl;
   500 	EngineRenew *er = (EngineRenew *)erl;
   483 
   501 
   484 	while (er) {
   502 	while (er) {
   485 		if (er->from == engine) return er;
   503 		if (er->from == engine && er->group_id == group) return er;
   486 		er = er->next;
   504 		er = er->next;
   487 	}
   505 	}
   488 	return NULL;
   506 	return NULL;
   489 }
   507 }
   490 
   508 
   499 		er = next;
   517 		er = next;
   500 	}
   518 	}
   501 	*erl = NULL; // Empty list
   519 	*erl = NULL; // Empty list
   502 }
   520 }
   503 
   521 
   504 EngineID EngineReplacement(EngineRenewList erl, EngineID engine)
   522 EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group)
   505 {
   523 {
   506 	const EngineRenew *er = GetEngineReplacement(erl, engine);
   524 	const EngineRenew *er = GetEngineReplacement(erl, engine, group);
   507 	return er == NULL ? INVALID_ENGINE : er->to;
   525 	return er == NULL ? INVALID_ENGINE : er->to;
   508 }
   526 }
   509 
   527 
   510 int32 AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, uint32 flags)
   528 int32 AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, GroupID group, uint32 flags)
   511 {
   529 {
   512 	EngineRenew *er;
   530 	EngineRenew *er;
   513 
   531 
   514 	/* Check if the old vehicle is already in the list */
   532 	/* Check if the old vehicle is already in the list */
   515 	er = GetEngineReplacement(*erl, old_engine);
   533 	er = GetEngineReplacement(*erl, old_engine, group);
   516 	if (er != NULL) {
   534 	if (er != NULL) {
   517 		if (flags & DC_EXEC) er->to = new_engine;
   535 		if (flags & DC_EXEC) er->to = new_engine;
   518 		return 0;
   536 		return 0;
   519 	}
   537 	}
   520 
   538 
   522 	if (er == NULL) return CMD_ERROR;
   540 	if (er == NULL) return CMD_ERROR;
   523 
   541 
   524 	if (flags & DC_EXEC) {
   542 	if (flags & DC_EXEC) {
   525 		er->from = old_engine;
   543 		er->from = old_engine;
   526 		er->to = new_engine;
   544 		er->to = new_engine;
       
   545 		er->group_id = group;
   527 
   546 
   528 		/* Insert before the first element */
   547 		/* Insert before the first element */
   529 		er->next = (EngineRenew *)(*erl);
   548 		er->next = (EngineRenew *)(*erl);
   530 		*erl = (EngineRenewList)er;
   549 		*erl = (EngineRenewList)er;
   531 	}
   550 	}
   532 
   551 
   533 	return 0;
   552 	return 0;
   534 }
   553 }
   535 
   554 
   536 int32 RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, uint32 flags)
   555 int32 RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, uint32 flags)
   537 {
   556 {
   538 	EngineRenew *er = (EngineRenew *)(*erl);
   557 	EngineRenew *er = (EngineRenew *)(*erl);
   539 	EngineRenew *prev = NULL;
   558 	EngineRenew *prev = NULL;
   540 
   559 
   541 	while (er)
   560 	while (er)
   542 	{
   561 	{
   543 		if (er->from == engine) {
   562 		if (er->from == engine && er->group_id == group) {
   544 			if (flags & DC_EXEC) {
   563 			if (flags & DC_EXEC) {
   545 				if (prev == NULL) { // First element
   564 				if (prev == NULL) { // First element
   546 					/* The second becomes the new first element */
   565 					/* The second becomes the new first element */
   547 					*erl = (EngineRenewList)er->next;
   566 					*erl = (EngineRenewList)er->next;
   548 				} else {
   567 				} else {
   559 
   578 
   560 	return CMD_ERROR;
   579 	return CMD_ERROR;
   561 }
   580 }
   562 
   581 
   563 static const SaveLoad _engine_renew_desc[] = {
   582 static const SaveLoad _engine_renew_desc[] = {
   564 	SLE_VAR(EngineRenew, from, SLE_UINT16),
   583 	    SLE_VAR(EngineRenew, from,     SLE_UINT16),
   565 	SLE_VAR(EngineRenew, to,   SLE_UINT16),
   584 	    SLE_VAR(EngineRenew, to,       SLE_UINT16),
   566 
   585 
   567 	SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS),
   586 	    SLE_REF(EngineRenew, next,     REF_ENGINE_RENEWS),
   568 
   587 	SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
   569 	SLE_END()
   588 	SLE_END()
   570 };
   589 };
   571 
   590 
   572 static void Save_ERNW()
   591 static void Save_ERNW()
   573 {
   592 {
   589 		if (!AddBlockIfNeeded(&_EngineRenew_pool, index))
   608 		if (!AddBlockIfNeeded(&_EngineRenew_pool, index))
   590 			error("EngineRenews: failed loading savegame: too many EngineRenews");
   609 			error("EngineRenews: failed loading savegame: too many EngineRenews");
   591 
   610 
   592 		er = GetEngineRenew(index);
   611 		er = GetEngineRenew(index);
   593 		SlObject(er, _engine_renew_desc);
   612 		SlObject(er, _engine_renew_desc);
       
   613 
       
   614 		/* Advanced vehicle lists got added */
       
   615 		if (CheckSavegameVersion(60)) er->group_id = DEFAULT_GROUP;
   594 	}
   616 	}
   595 }
   617 }
   596 
   618 
   597 static const SaveLoad _engine_desc[] = {
   619 static const SaveLoad _engine_desc[] = {
   598 	SLE_CONDVAR(Engine, intro_date,          SLE_FILE_U16 | SLE_VAR_I32,  0,  30),
   620 	SLE_CONDVAR(Engine, intro_date,          SLE_FILE_U16 | SLE_VAR_I32,  0,  30),