481 { |
481 { |
482 Player *p; |
482 Player *p; |
483 // Find a free slot |
483 // Find a free slot |
484 FOR_ALL_PLAYERS(p) { |
484 FOR_ALL_PLAYERS(p) { |
485 if (!p->is_active) { |
485 if (!p->is_active) { |
486 int i = p->index; |
486 PlayerID i = p->index; |
487 memset(p, 0, sizeof(Player)); |
487 memset(p, 0, sizeof(Player)); |
488 p->index = i; |
488 p->index = i; |
489 return p; |
489 return p; |
490 } |
490 } |
491 } |
491 } |
492 return NULL; |
492 return NULL; |
493 } |
493 } |
494 |
494 |
495 void ResetPlayerLivery(Player *p) |
495 void ResetPlayerLivery(Player *p) |
496 { |
496 { |
497 LiveryScheme scheme; |
497 for (LiveryScheme scheme = LS_BEGIN; scheme < LS_END; scheme++) { |
498 |
|
499 for (scheme = 0; scheme < LS_END; scheme++) { |
|
500 p->livery[scheme].in_use = false; |
498 p->livery[scheme].in_use = false; |
501 p->livery[scheme].colour1 = p->player_color; |
499 p->livery[scheme].colour1 = p->player_color; |
502 p->livery[scheme].colour2 = p->player_color; |
500 p->livery[scheme].colour2 = p->player_color; |
503 } |
501 } |
504 } |
502 } |
581 _next_competitor_start += _network_server ? InteractiveRandomRange(60 * DAY_TICKS) : RandomRange(60 * DAY_TICKS); |
579 _next_competitor_start += _network_server ? InteractiveRandomRange(60 * DAY_TICKS) : RandomRange(60 * DAY_TICKS); |
582 } |
580 } |
583 |
581 |
584 void InitializePlayers(void) |
582 void InitializePlayers(void) |
585 { |
583 { |
586 uint i; |
|
587 |
|
588 memset(_players, 0, sizeof(_players)); |
584 memset(_players, 0, sizeof(_players)); |
589 for (i = 0; i != MAX_PLAYERS; i++) _players[i].index = i; |
585 for (PlayerID i = PLAYER_FIRST; i != MAX_PLAYERS; i++) _players[i].index = i; |
590 _cur_player_tick_index = 0; |
586 _cur_player_tick_index = 0; |
591 } |
587 } |
592 |
588 |
593 void OnTick_Players(void) |
589 void OnTick_Players(void) |
594 { |
590 { |
595 Player *p; |
591 Player *p; |
596 |
592 |
597 if (_game_mode == GM_EDITOR) return; |
593 if (_game_mode == GM_EDITOR) return; |
598 |
594 |
599 p = GetPlayer(_cur_player_tick_index); |
595 p = GetPlayer((PlayerID)_cur_player_tick_index); |
600 _cur_player_tick_index = (_cur_player_tick_index + 1) % MAX_PLAYERS; |
596 _cur_player_tick_index = (_cur_player_tick_index + 1) % MAX_PLAYERS; |
601 if (p->name_1 != 0) GenerateCompanyName(p); |
597 if (p->name_1 != 0) GenerateCompanyName(p); |
602 |
598 |
603 if (AI_AllowNewAI() && _game_mode != GM_MENU && !--_next_competitor_start) |
599 if (AI_AllowNewAI() && _game_mode != GM_MENU && !--_next_competitor_start) |
604 MaybeStartNewPlayer(); |
600 MaybeStartNewPlayer(); |
926 break; |
922 break; |
927 |
923 |
928 case 2: { /* Delete a player */ |
924 case 2: { /* Delete a player */ |
929 Player *p; |
925 Player *p; |
930 |
926 |
931 if (!IsValidPlayer(p2)) return CMD_ERROR; |
927 if (!IsValidPlayer((PlayerID)p2)) return CMD_ERROR; |
932 |
928 |
933 if (!(flags & DC_EXEC)) return 0; |
929 if (!(flags & DC_EXEC)) return 0; |
934 |
930 |
935 p = GetPlayer(p2); |
931 p = GetPlayer((PlayerID)p2); |
936 |
932 |
937 /* Only allow removal of HUMAN companies */ |
933 /* Only allow removal of HUMAN companies */ |
938 if (IsHumanPlayer(p->index)) { |
934 if (IsHumanPlayer(p->index)) { |
939 /* Delete any open window of the company */ |
935 /* Delete any open window of the company */ |
940 DeletePlayerWindows(p->index); |
936 DeletePlayerWindows(p->index); |
951 RemoveAllEngineReplacementForPlayer(p); |
947 RemoveAllEngineReplacementForPlayer(p); |
952 |
948 |
953 } break; |
949 } break; |
954 |
950 |
955 case 3: { /* Merge a company (#1) into another company (#2), elimination company #1 */ |
951 case 3: { /* Merge a company (#1) into another company (#2), elimination company #1 */ |
956 PlayerID pid_old = GB(p2, 0, 16); |
952 PlayerID pid_old = (PlayerID)GB(p2, 0, 16); |
957 PlayerID pid_new = GB(p2, 16, 16); |
953 PlayerID pid_new = (PlayerID)GB(p2, 16, 16); |
958 |
954 |
959 if (!IsValidPlayer(pid_old) || !IsValidPlayer(pid_new)) return CMD_ERROR; |
955 if (!IsValidPlayer(pid_old) || !IsValidPlayer(pid_new)) return CMD_ERROR; |
960 |
956 |
961 if (!(flags & DC_EXEC)) return CMD_ERROR; |
957 if (!(flags & DC_EXEC)) return CMD_ERROR; |
962 |
958 |
1321 |
1317 |
1322 static void Load_PLYR(void) |
1318 static void Load_PLYR(void) |
1323 { |
1319 { |
1324 int index; |
1320 int index; |
1325 while ((index = SlIterateArray()) != -1) { |
1321 while ((index = SlIterateArray()) != -1) { |
1326 Player *p = GetPlayer(index); |
1322 Player *p = GetPlayer((PlayerID)index); |
1327 SaveLoad_PLYR(p); |
1323 SaveLoad_PLYR(p); |
1328 _player_colors[index] = p->player_color; |
1324 _player_colors[index] = p->player_color; |
1329 UpdatePlayerMoney32(p); |
1325 UpdatePlayerMoney32(p); |
1330 |
1326 |
1331 /* This is needed so an AI is attached to a loaded AI */ |
1327 /* This is needed so an AI is attached to a loaded AI */ |
1332 if (p->is_ai && (!_networking || _network_server) && _ai.enabled) |
1328 if (p->is_ai && (!_networking || _network_server) && _ai.enabled) |
1333 AI_StartNewAI(p->index); |
1329 AI_StartNewAI(p->index); |
1334 } |
1330 } |
1335 } |
1331 } |
1336 |
1332 |
1337 const ChunkHandler _player_chunk_handlers[] = { |
1333 extern const ChunkHandler _player_chunk_handlers[] = { |
1338 { 'PLYR', Save_PLYR, Load_PLYR, CH_ARRAY | CH_LAST}, |
1334 { 'PLYR', Save_PLYR, Load_PLYR, CH_ARRAY | CH_LAST}, |
1339 }; |
1335 }; |