engine.c
changeset 1786 7cfd46c3fcc4
parent 1560 d040e4763f45
child 1802 da61740cc1e7
equal deleted inserted replaced
1785:d3f3496b5943 1786:7cfd46c3fcc4
   644 	_userstring[USERSTRING_LEN - 1] = '\0';
   644 	_userstring[USERSTRING_LEN - 1] = '\0';
   645 	return STR_SPEC_USERSTRING;
   645 	return STR_SPEC_USERSTRING;
   646 }
   646 }
   647 
   647 
   648 
   648 
   649 void AcceptEnginePreview(Engine *e, int player)
   649 void AcceptEnginePreview(Engine *e, PlayerID player)
   650 {
   650 {
   651 	Player *p;
   651 	Player *p = DEREF_PLAYER(player);
   652 
   652 
   653 	SETBIT(e->player_avail, player);
   653 	SETBIT(e->player_avail, player);
   654 
   654 
   655 	p = DEREF_PLAYER(player);
   655 	UPDATE_PLAYER_RAILTYPE(e, p);
   656 
       
   657 	UPDATE_PLAYER_RAILTYPE(e,p);
       
   658 
   656 
   659 	e->preview_player = 0xFF;
   657 	e->preview_player = 0xFF;
   660 	InvalidateWindowClasses(WC_BUILD_VEHICLE);
   658 	InvalidateWindowClasses(WC_BUILD_VEHICLE);
   661 	InvalidateWindowClasses(WC_REPLACE_VEHICLE);
   659 	InvalidateWindowClasses(WC_REPLACE_VEHICLE);
   662 }
   660 }
   663 
   661 
       
   662 static PlayerID GetBestPlayer(PlayerID pp)
       
   663 {
       
   664 	const Player *p;
       
   665 	int32 best_hist;
       
   666 	PlayerID best_player;
       
   667 	uint mask = 0;
       
   668 
       
   669 	do {
       
   670 		best_hist = -1;
       
   671 		best_player = -1;
       
   672 		FOR_ALL_PLAYERS(p) {
       
   673 			if (p->is_active && p->block_preview == 0 && !HASBIT(mask, p->index) &&
       
   674 					p->old_economy[0].performance_history > best_hist) {
       
   675 				best_hist = p->old_economy[0].performance_history;
       
   676 				best_player = p->index;
       
   677 			}
       
   678 		}
       
   679 
       
   680 		if (best_player == (PlayerID)-1) return -1;
       
   681 
       
   682 		SETBIT(mask, best_player);
       
   683 	} while (--pp != 0);
       
   684 
       
   685 	return best_player;
       
   686 }
       
   687 
   664 void EnginesDailyLoop(void)
   688 void EnginesDailyLoop(void)
   665 {
   689 {
   666 	Engine *e;
   690 	Engine *e;
   667 	int i,num;
   691 	int i;
   668 	Player *p;
   692 
   669 	uint mask;
   693 	if (_cur_year >= 130) return;
   670 	int32 best_hist;
   694 
   671 	int best_player;
   695 	for (e = _engines, i = 0; i != TOTAL_NUM_ENGINES; e++, i++) {
   672 
       
   673 	if (_cur_year >= 130)
       
   674 		return;
       
   675 
       
   676 	for(e=_engines,i=0; i!=TOTAL_NUM_ENGINES; e++,i++) {
       
   677 		if (e->flags & ENGINE_INTRODUCING) {
   696 		if (e->flags & ENGINE_INTRODUCING) {
   678 			if (e->flags & ENGINE_PREVIEWING) {
   697 			if (e->flags & ENGINE_PREVIEWING) {
   679 				if (e->preview_player != 0xFF && !--e->preview_wait) {
   698 				if (e->preview_player != 0xFF && !--e->preview_wait) {
   680 					e->flags &= ~ENGINE_PREVIEWING;
   699 					e->flags &= ~ENGINE_PREVIEWING;
   681 					DeleteWindowById(WC_ENGINE_PREVIEW, i);
   700 					DeleteWindowById(WC_ENGINE_PREVIEW, i);
   682 					e->preview_player++;
   701 					e->preview_player++;
   683 				}
   702 				}
   684 			} else if (e->preview_player != 0xFF) {
   703  			} else if (e->preview_player != 0xFF) {
   685 				num = e->preview_player;
   704 				PlayerID best_player = GetBestPlayer(e->preview_player);
   686 				mask = 0;
   705 
   687 				do {
   706 				if (best_player == (PlayerID)-1) {
   688 					best_hist = -1;
   707 					e->preview_player = 0xFF;
   689 					best_player = -1;
   708 					continue;
   690 					FOR_ALL_PLAYERS(p) {
   709 				}
   691 						if (p->is_active && p->block_preview == 0 && !HASBIT(mask,p->index) &&
       
   692 								p->old_economy[0].performance_history > best_hist) {
       
   693 							best_hist = p->old_economy[0].performance_history;
       
   694 							best_player = p->index;
       
   695 						}
       
   696 					}
       
   697 					if (best_player == -1) {
       
   698 						e->preview_player = 0xFF;
       
   699 						goto next_engine;
       
   700 					}
       
   701 					mask |= (1 << best_player);
       
   702 				} while (--num != 0);
       
   703 
   710 
   704 				if (!IS_HUMAN_PLAYER(best_player)) {
   711 				if (!IS_HUMAN_PLAYER(best_player)) {
   705 					/* TTDBUG: TTD has a bug here */
   712 					/* XXX - TTDBUG: TTD has a bug here ???? */
   706 					AcceptEnginePreview(e, best_player);
   713 					AcceptEnginePreview(e, best_player);
   707 				} else {
   714 				} else {
   708 					e->flags |= ENGINE_PREVIEWING;
   715 					e->flags |= ENGINE_PREVIEWING;
   709 					e->preview_wait = 20;
   716 					e->preview_wait = 20;
   710 					if (IS_INTERACTIVE_PLAYER(best_player)) {
   717 					if (IS_INTERACTIVE_PLAYER(best_player))
   711 						ShowEnginePreviewWindow(i);
   718 						ShowEnginePreviewWindow(i);
   712 					}
       
   713 				}
   719 				}
   714 			}
   720 			}
   715 		}
   721 		}
   716 		next_engine:;
   722 	}
   717 	}
   723 }
   718 }
   724 
   719 
   725 /** Accept an engine prototype. XXX - it is possible that the top-player
       
   726  * changes while you are waiting to accept the offer? Then it becomes invalid
       
   727  * @param x,y unused
       
   728  * @param p1 engine-prototype offered
       
   729  * @param p2 unused
       
   730  */
   720 int32 CmdWantEnginePreview(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   731 int32 CmdWantEnginePreview(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   721 {
   732 {
   722 	if (flags & DC_EXEC) {
   733 	Engine *e;
   723 		AcceptEnginePreview(&_engines[p1], _current_player);
   734 	if (!IsEngineIndex(p1)) return CMD_ERROR;
   724 	}
   735 
       
   736 	e = DEREF_ENGINE(p1);
       
   737 	if (GetBestPlayer(e->preview_player) != _current_player) return CMD_ERROR;
       
   738 
       
   739 	if (flags & DC_EXEC)
       
   740 		AcceptEnginePreview(e, _current_player);
       
   741 
   725 	return 0;
   742 	return 0;
   726 }
   743 }
   727 
   744 
   728 // Determine if an engine type is a wagon (and not a loco)
   745 // Determine if an engine type is a wagon (and not a loco)
   729 static bool IsWagon(byte index)
   746 static bool IsWagon(byte index)
   816 		}
   833 		}
   817 	}
   834 	}
   818 	AdjustAvailAircraft();
   835 	AdjustAvailAircraft();
   819 }
   836 }
   820 
   837 
       
   838 /** Rename an engine.
       
   839  * @param x,y unused
       
   840  * @param p1 engine ID to rename
       
   841  * @param p2 unused
       
   842  */
   821 int32 CmdRenameEngine(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   843 int32 CmdRenameEngine(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   822 {
   844 {
   823 	StringID str;
   845 	StringID str;
   824 
   846 
       
   847 	if (!IsEngineIndex(p1)) return CMD_ERROR;
       
   848 
   825 	str = AllocateNameUnique((const char*)_decode_parameters, 0);
   849 	str = AllocateNameUnique((const char*)_decode_parameters, 0);
   826 	if (str == 0)
   850 	if (str == 0) return CMD_ERROR;
   827 		return CMD_ERROR;
       
   828 
   851 
   829 	if (flags & DC_EXEC) {
   852 	if (flags & DC_EXEC) {
   830 		StringID old_str = _engine_name_strings[p1];
   853 		StringID old_str = _engine_name_strings[p1];
   831 		_engine_name_strings[p1] = str;
   854 		_engine_name_strings[p1] = str;
   832 		DeleteName(old_str);
   855 		DeleteName(old_str);
   924 bool IsEngineBuildable(uint engine, byte type)
   947 bool IsEngineBuildable(uint engine, byte type)
   925 {
   948 {
   926 	const Engine *e;
   949 	const Engine *e;
   927 
   950 
   928 	// check if it's an engine that is in the engine array
   951 	// check if it's an engine that is in the engine array
   929 	if (engine >= TOTAL_NUM_ENGINES) return false;
   952 	if (!IsEngineIndex(engine)) return false;
   930 
   953 
   931 	e = DEREF_ENGINE(engine);
   954 	e = DEREF_ENGINE(engine);
   932 
   955 
   933 	// check if it's an engine of specified type
   956 	// check if it's an engine of specified type
   934 	if (e->type != type) return false;
   957 	if (e->type != type) return false;