src/players.cpp
branchNewGRF_ports
changeset 6871 5a9dc001e1ad
parent 6725 23339968083f
child 6872 1c4a4a609f85
equal deleted inserted replaced
6870:ca3fd1fbe311 6871:5a9dc001e1ad
    26 #include "ai/ai.h"
    26 #include "ai/ai.h"
    27 #include "date.h"
    27 #include "date.h"
    28 #include "window.h"
    28 #include "window.h"
    29 #include "player_face.h"
    29 #include "player_face.h"
    30 #include "group.h"
    30 #include "group.h"
       
    31 #include "settings.h"
    31 
    32 
    32 /**
    33 /**
    33  * Sets the local player and updates the patch settings that are set on a
    34  * Sets the local player and updates the patch settings that are set on a
    34  * per-company (player) basis to reflect the core's state in the GUI.
    35  * per-company (player) basis to reflect the core's state in the GUI.
    35  * @param new_player the new player
    36  * @param new_player the new player
    87 PlayerFace ConvertFromOldPlayerFace(uint32 face)
    88 PlayerFace ConvertFromOldPlayerFace(uint32 face)
    88 {
    89 {
    89 	PlayerFace pf = 0;
    90 	PlayerFace pf = 0;
    90 	GenderEthnicity ge = GE_WM;
    91 	GenderEthnicity ge = GE_WM;
    91 
    92 
    92 	if (HASBIT(face, 31)) SetBitT(ge, GENDER_FEMALE);
    93 	if (HasBit(face, 31)) SetBit(ge, GENDER_FEMALE);
    93 	if (HASBIT(face, 27) && (HASBIT(face, 26) == HASBIT(face, 19))) SetBitT(ge, ETHNICITY_BLACK);
    94 	if (HasBit(face, 27) && (HasBit(face, 26) == HasBit(face, 19))) SetBit(ge, ETHNICITY_BLACK);
    94 
    95 
    95 	SetPlayerFaceBits(pf, PFV_GEN_ETHN,    ge, ge);
    96 	SetPlayerFaceBits(pf, PFV_GEN_ETHN,    ge, ge);
    96 	SetPlayerFaceBits(pf, PFV_HAS_GLASSES, ge, GB(face, 28, 3) <= 1);
    97 	SetPlayerFaceBits(pf, PFV_HAS_GLASSES, ge, GB(face, 28, 3) <= 1);
    97 	SetPlayerFaceBits(pf, PFV_EYE_COLOUR,  ge, clampu(GB(face, 20, 3), 5, 7) - 5);
    98 	SetPlayerFaceBits(pf, PFV_EYE_COLOUR,  ge, HasBit(ge, ETHNICITY_BLACK) ? 0 : ClampU(GB(face, 20, 3), 5, 7) - 5);
    98 	SetPlayerFaceBits(pf, PFV_CHIN,        ge, ScalePlayerFaceValue(PFV_CHIN,     ge, GB(face,  4, 2)));
    99 	SetPlayerFaceBits(pf, PFV_CHIN,        ge, ScalePlayerFaceValue(PFV_CHIN,     ge, GB(face,  4, 2)));
    99 	SetPlayerFaceBits(pf, PFV_EYEBROWS,    ge, ScalePlayerFaceValue(PFV_EYEBROWS, ge, GB(face,  6, 4)));
   100 	SetPlayerFaceBits(pf, PFV_EYEBROWS,    ge, ScalePlayerFaceValue(PFV_EYEBROWS, ge, GB(face,  6, 4)));
   100 	SetPlayerFaceBits(pf, PFV_HAIR,        ge, ScalePlayerFaceValue(PFV_HAIR,     ge, GB(face, 16, 4)));
   101 	SetPlayerFaceBits(pf, PFV_HAIR,        ge, ScalePlayerFaceValue(PFV_HAIR,     ge, GB(face, 16, 4)));
   101 	SetPlayerFaceBits(pf, PFV_JACKET,      ge, ScalePlayerFaceValue(PFV_JACKET,   ge, GB(face, 20, 2)));
   102 	SetPlayerFaceBits(pf, PFV_JACKET,      ge, ScalePlayerFaceValue(PFV_JACKET,   ge, GB(face, 20, 2)));
   102 	SetPlayerFaceBits(pf, PFV_COLLAR,      ge, ScalePlayerFaceValue(PFV_COLLAR,   ge, GB(face, 22, 2)));
   103 	SetPlayerFaceBits(pf, PFV_COLLAR,      ge, ScalePlayerFaceValue(PFV_COLLAR,   ge, GB(face, 22, 2)));
   103 	SetPlayerFaceBits(pf, PFV_GLASSES,     ge, GB(face, 28, 1));
   104 	SetPlayerFaceBits(pf, PFV_GLASSES,     ge, GB(face, 28, 1));
   104 
   105 
   105 	uint lips = GB(face, 10, 4);
   106 	uint lips = GB(face, 10, 4);
   106 	if (!HASBIT(ge, GENDER_FEMALE) && lips < 4) {
   107 	if (!HasBit(ge, GENDER_FEMALE) && lips < 4) {
   107 		SetPlayerFaceBits(pf, PFV_HAS_MOUSTACHE, ge, true);
   108 		SetPlayerFaceBits(pf, PFV_HAS_MOUSTACHE, ge, true);
   108 		SetPlayerFaceBits(pf, PFV_MOUSTACHE,     ge, max(lips, 1U) - 1);
   109 		SetPlayerFaceBits(pf, PFV_MOUSTACHE,     ge, max(lips, 1U) - 1);
   109 	} else {
   110 	} else {
   110 		if (!HASBIT(ge, GENDER_FEMALE)) {
   111 		if (!HasBit(ge, GENDER_FEMALE)) {
   111 			lips = lips * 15 / 16;
   112 			lips = lips * 15 / 16;
   112 			lips -= 3;
   113 			lips -= 3;
   113 			if (HASBIT(ge, ETHNICITY_BLACK) && lips > 8) lips = 0;
   114 			if (HasBit(ge, ETHNICITY_BLACK) && lips > 8) lips = 0;
   114 		} else {
   115 		} else {
   115 			lips = ScalePlayerFaceValue(PFV_LIPS, ge, lips);
   116 			lips = ScalePlayerFaceValue(PFV_LIPS, ge, lips);
   116 		}
   117 		}
   117 		SetPlayerFaceBits(pf, PFV_LIPS, ge, lips);
   118 		SetPlayerFaceBits(pf, PFV_LIPS, ge, lips);
   118 
   119 
   124 		}
   125 		}
   125 		SetPlayerFaceBits(pf, PFV_NOSE, ge, nose);
   126 		SetPlayerFaceBits(pf, PFV_NOSE, ge, nose);
   126 	}
   127 	}
   127 
   128 
   128 	uint tie_earring = GB(face, 24, 4);
   129 	uint tie_earring = GB(face, 24, 4);
   129 	if (!HASBIT(ge, GENDER_FEMALE) || tie_earring < 3) { // Not all females have an earring
   130 	if (!HasBit(ge, GENDER_FEMALE) || tie_earring < 3) { // Not all females have an earring
   130 		if (HASBIT(ge, GENDER_FEMALE)) SetPlayerFaceBits(pf, PFV_HAS_TIE_EARRING, ge, true);
   131 		if (HasBit(ge, GENDER_FEMALE)) SetPlayerFaceBits(pf, PFV_HAS_TIE_EARRING, ge, true);
   131 		SetPlayerFaceBits(pf, PFV_TIE_EARRING, ge, HASBIT(ge, GENDER_FEMALE) ? tie_earring : ScalePlayerFaceValue(PFV_TIE_EARRING, ge, tie_earring / 2));
   132 		SetPlayerFaceBits(pf, PFV_TIE_EARRING, ge, HasBit(ge, GENDER_FEMALE) ? tie_earring : ScalePlayerFaceValue(PFV_TIE_EARRING, ge, tie_earring / 2));
   132 	}
   133 	}
   133 
   134 
   134 	return pf;
   135 	return pf;
   135 }
   136 }
   136 
   137 
   143 bool IsValidPlayerFace(PlayerFace pf)
   144 bool IsValidPlayerFace(PlayerFace pf)
   144 {
   145 {
   145 	if (!ArePlayerFaceBitsValid(pf, PFV_GEN_ETHN, GE_WM)) return false;
   146 	if (!ArePlayerFaceBitsValid(pf, PFV_GEN_ETHN, GE_WM)) return false;
   146 
   147 
   147 	GenderEthnicity ge   = (GenderEthnicity)GetPlayerFaceBits(pf, PFV_GEN_ETHN, GE_WM);
   148 	GenderEthnicity ge   = (GenderEthnicity)GetPlayerFaceBits(pf, PFV_GEN_ETHN, GE_WM);
   148 	bool has_moustache   = !HASBIT(ge, GENDER_FEMALE) && GetPlayerFaceBits(pf, PFV_HAS_MOUSTACHE,   ge) != 0;
   149 	bool has_moustache   = !HasBit(ge, GENDER_FEMALE) && GetPlayerFaceBits(pf, PFV_HAS_MOUSTACHE,   ge) != 0;
   149 	bool has_tie_earring = !HASBIT(ge, GENDER_FEMALE) || GetPlayerFaceBits(pf, PFV_HAS_TIE_EARRING, ge) != 0;
   150 	bool has_tie_earring = !HasBit(ge, GENDER_FEMALE) || GetPlayerFaceBits(pf, PFV_HAS_TIE_EARRING, ge) != 0;
   150 	bool has_glasses     = GetPlayerFaceBits(pf, PFV_HAS_GLASSES, ge) != 0;
   151 	bool has_glasses     = GetPlayerFaceBits(pf, PFV_HAS_GLASSES, ge) != 0;
   151 
   152 
   152 	if (!ArePlayerFaceBitsValid(pf, PFV_EYE_COLOUR, ge)) return false;
   153 	if (!ArePlayerFaceBitsValid(pf, PFV_EYE_COLOUR, ge)) return false;
   153 	for (PlayerFaceVariable pfv = PFV_CHEEKS; pfv < PFV_END; pfv++) {
   154 	for (PlayerFaceVariable pfv = PFV_CHEEKS; pfv < PFV_END; pfv++) {
   154 		switch (pfv) {
   155 		switch (pfv) {
   194 
   195 
   195 	tmp = CommandCost(p->yearly_expenses[0][_yearly_expenses_type]);
   196 	tmp = CommandCost(p->yearly_expenses[0][_yearly_expenses_type]);
   196 	tmp.AddCost(cost);
   197 	tmp.AddCost(cost);
   197 	p->yearly_expenses[0][_yearly_expenses_type] = tmp.GetCost();
   198 	p->yearly_expenses[0][_yearly_expenses_type] = tmp.GetCost();
   198 
   199 
   199 	if (HASBIT(1 << EXPENSES_TRAIN_INC    |
   200 	if (HasBit(1 << EXPENSES_TRAIN_INC    |
   200 	           1 << EXPENSES_ROADVEH_INC  |
   201 	           1 << EXPENSES_ROADVEH_INC  |
   201 	           1 << EXPENSES_AIRCRAFT_INC |
   202 	           1 << EXPENSES_AIRCRAFT_INC |
   202 	           1 << EXPENSES_SHIP_INC, _yearly_expenses_type)) {
   203 	           1 << EXPENSES_SHIP_INC, _yearly_expenses_type)) {
   203 		tmp = CommandCost(p->cur_economy.income);
   204 		tmp = CommandCost(p->cur_economy.income);
   204 		tmp.AddCost(-cost.GetCost());
   205 		tmp.AddCost(-cost.GetCost());
   205 		p->cur_economy.income = tmp.GetCost();
   206 		p->cur_economy.income = tmp.GetCost();
   206 	} else if (HASBIT(1 << EXPENSES_TRAIN_RUN    |
   207 	} else if (HasBit(1 << EXPENSES_TRAIN_RUN    |
   207 	                  1 << EXPENSES_ROADVEH_RUN  |
   208 	                  1 << EXPENSES_ROADVEH_RUN  |
   208 	                  1 << EXPENSES_AIRCRAFT_RUN |
   209 	                  1 << EXPENSES_AIRCRAFT_RUN |
   209 	                  1 << EXPENSES_SHIP_RUN     |
   210 	                  1 << EXPENSES_SHIP_RUN     |
   210 	                  1 << EXPENSES_PROPERTY     |
   211 	                  1 << EXPENSES_PROPERTY     |
   211 	                  1 << EXPENSES_LOAN_INT, _yearly_expenses_type)) {
   212 	                  1 << EXPENSES_LOAN_INT, _yearly_expenses_type)) {
   296 	tile = p->last_build_coordinate;
   297 	tile = p->last_build_coordinate;
   297 	if (tile == 0) return;
   298 	if (tile == 0) return;
   298 
   299 
   299 	t = ClosestTownFromTile(tile, (uint)-1);
   300 	t = ClosestTownFromTile(tile, (uint)-1);
   300 
   301 
   301 	if (IS_INT_INSIDE(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST+1)) {
   302 	if (IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST+1)) {
   302 		str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_PLAYERNAME_START;
   303 		str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_PLAYERNAME_START;
   303 		strp = t->townnameparts;
   304 		strp = t->townnameparts;
   304 
   305 
   305 verify_name:;
   306 verify_name:;
   306 		/* No player must have this name already */
   307 		/* No player must have this name already */
   453 		p->livery[scheme].colour1 = p->player_color;
   454 		p->livery[scheme].colour1 = p->player_color;
   454 		p->livery[scheme].colour2 = p->player_color;
   455 		p->livery[scheme].colour2 = p->player_color;
   455 	}
   456 	}
   456 }
   457 }
   457 
   458 
       
   459 /**
       
   460  * Create a new player and sets all player variables default values
       
   461  *
       
   462  * @param is_ai is a ai player?
       
   463  * @return the player struct
       
   464  */
   458 Player *DoStartupNewPlayer(bool is_ai)
   465 Player *DoStartupNewPlayer(bool is_ai)
   459 {
   466 {
   460 	Player *p;
   467 	Player *p;
   461 
   468 
   462 	p = AllocatePlayer();
   469 	p = AllocatePlayer();
   476 	p->share_owners[0] = p->share_owners[1] = p->share_owners[2] = p->share_owners[3] = PLAYER_SPECTATOR;
   483 	p->share_owners[0] = p->share_owners[1] = p->share_owners[2] = p->share_owners[3] = PLAYER_SPECTATOR;
   477 
   484 
   478 	p->avail_railtypes = GetPlayerRailtypes(p->index);
   485 	p->avail_railtypes = GetPlayerRailtypes(p->index);
   479 	p->avail_roadtypes = GetPlayerRoadtypes(p->index);
   486 	p->avail_roadtypes = GetPlayerRoadtypes(p->index);
   480 	p->inaugurated_year = _cur_year;
   487 	p->inaugurated_year = _cur_year;
   481 	p->face = ConvertFromOldPlayerFace(Random());
   488 	RandomPlayerFaceBits(p->face, (GenderEthnicity)Random(), false); // create a random player face
   482 
   489 
   483 	/* Engine renewal settings */
   490 	/* Engine renewal settings */
   484 	p->engine_renew_list = NULL;
   491 	p->engine_renew_list = NULL;
   485 	p->renew_keep_length = false;
   492 	p->renew_keep_length = false;
   486 	p->engine_renew = false;
   493 	p->engine_renew = _patches_newgame.autorenew;
   487 	p->engine_renew_months = -6;
   494 	p->engine_renew_months = _patches_newgame.autorenew_months;
   488 	p->engine_renew_money = 100000;
   495 	p->engine_renew_money = _patches_newgame.autorenew_money;
   489 
   496 
   490 	GeneratePresidentName(p);
   497 	GeneratePresidentName(p);
   491 
   498 
   492 	InvalidateWindow(WC_GRAPH_LEGEND, 0);
   499 	InvalidateWindow(WC_GRAPH_LEGEND, 0);
   493 	InvalidateWindow(WC_TOOLBAR_MENU, 0);
   500 	InvalidateWindow(WC_TOOLBAR_MENU, 0);
   588 
   595 
   589 	for (i = 0; i != TOTAL_NUM_ENGINES; i++) {
   596 	for (i = 0; i != TOTAL_NUM_ENGINES; i++) {
   590 		const Engine* e = GetEngine(i);
   597 		const Engine* e = GetEngine(i);
   591 		const EngineInfo *ei = EngInfo(i);
   598 		const EngineInfo *ei = EngInfo(i);
   592 
   599 
   593 		if (e->type == VEH_TRAIN && HASBIT(ei->climates, _opt.landscape) &&
   600 		if (e->type == VEH_TRAIN && HasBit(ei->climates, _opt.landscape) &&
   594 				(HASBIT(e->player_avail, p) || _date >= e->intro_date + 365)) {
   601 				(HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
   595 			const RailVehicleInfo *rvi = RailVehInfo(i);
   602 			const RailVehicleInfo *rvi = RailVehInfo(i);
   596 
   603 
   597 			if (rvi->railveh_type != RAILVEH_WAGON) {
   604 			if (rvi->railveh_type != RAILVEH_WAGON) {
   598 				assert(rvi->railtype < RAILTYPE_END);
   605 				assert(rvi->railtype < RAILTYPE_END);
   599 				SETBIT(rt, rvi->railtype);
   606 				SetBit(rt, rvi->railtype);
   600 			}
   607 			}
   601 		}
   608 		}
   602 	}
   609 	}
   603 
   610 
   604 	return rt;
   611 	return rt;
   611 
   618 
   612 	for (i = 0; i != TOTAL_NUM_ENGINES; i++) {
   619 	for (i = 0; i != TOTAL_NUM_ENGINES; i++) {
   613 		const Engine* e = GetEngine(i);
   620 		const Engine* e = GetEngine(i);
   614 		const EngineInfo *ei = EngInfo(i);
   621 		const EngineInfo *ei = EngInfo(i);
   615 
   622 
   616 		if (e->type == VEH_ROAD && HASBIT(ei->climates, _opt.landscape) &&
   623 		if (e->type == VEH_ROAD && HasBit(ei->climates, _opt.landscape) &&
   617 				(HASBIT(e->player_avail, p) || _date >= e->intro_date + 365)) {
   624 				(HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
   618 			SETBIT(rt, HASBIT(ei->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD);
   625 			SetBit(rt, HasBit(ei->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD);
   619 		}
   626 		}
   620 	}
   627 	}
   621 
   628 
   622 	return rt;
   629 	return rt;
   623 }
   630 }
   668 	if (!IsValidPlayer(_current_player)) return CMD_ERROR;
   675 	if (!IsValidPlayer(_current_player)) return CMD_ERROR;
   669 
   676 
   670 	p = GetPlayer(_current_player);
   677 	p = GetPlayer(_current_player);
   671 	switch (GB(p1, 0, 3)) {
   678 	switch (GB(p1, 0, 3)) {
   672 		case 0:
   679 		case 0:
   673 			if (p->engine_renew == (bool)GB(p2, 0, 1))
   680 			if (p->engine_renew == HasBit(p2, 0))
   674 				return CMD_ERROR;
   681 				return CMD_ERROR;
   675 
   682 
   676 			if (flags & DC_EXEC) {
   683 			if (flags & DC_EXEC) {
   677 				p->engine_renew = (bool)GB(p2, 0, 1);
   684 				p->engine_renew = HasBit(p2, 0);
   678 				if (IsLocalPlayer()) {
   685 				if (IsLocalPlayer()) {
   679 					_patches.autorenew = p->engine_renew;
   686 					_patches.autorenew = p->engine_renew;
   680 					InvalidateWindow(WC_GAME_OPTIONS, 0);
   687 					InvalidateWindow(WC_GAME_OPTIONS, 0);
   681 				}
   688 				}
   682 			}
   689 			}
   726 				if (GetEngine(new_engine_type)->type == VEH_AIRCRAFT &&
   733 				if (GetEngine(new_engine_type)->type == VEH_AIRCRAFT &&
   727 						(AircraftVehInfo(old_engine_type)->subtype & AIR_CTOL) != (AircraftVehInfo(new_engine_type)->subtype & AIR_CTOL))
   734 						(AircraftVehInfo(old_engine_type)->subtype & AIR_CTOL) != (AircraftVehInfo(new_engine_type)->subtype & AIR_CTOL))
   728 					return CMD_ERROR;
   735 					return CMD_ERROR;
   729 
   736 
   730 				/* make sure that the player can actually buy the new engine */
   737 				/* make sure that the player can actually buy the new engine */
   731 				if (!HASBIT(GetEngine(new_engine_type)->player_avail, _current_player))
   738 				if (!HasBit(GetEngine(new_engine_type)->player_avail, _current_player))
   732 					return CMD_ERROR;
   739 					return CMD_ERROR;
   733 
   740 
   734 				cost = AddEngineReplacementForPlayer(p, old_engine_type, new_engine_type, id_g, flags);
   741 				cost = AddEngineReplacementForPlayer(p, old_engine_type, new_engine_type, id_g, flags);
   735 			} else {
   742 			} else {
   736 				cost = RemoveEngineReplacementForPlayer(p, old_engine_type,id_g, flags);
   743 				cost = RemoveEngineReplacementForPlayer(p, old_engine_type,id_g, flags);
   741 			return cost;
   748 			return cost;
   742 		}
   749 		}
   743 
   750 
   744 		case 4:
   751 		case 4:
   745 			if (flags & DC_EXEC) {
   752 			if (flags & DC_EXEC) {
   746 				p->engine_renew = (bool)GB(p1, 15, 1);
   753 				p->engine_renew = HasBit(p1, 15);
   747 				p->engine_renew_months = (int16)GB(p1, 16, 16);
   754 				p->engine_renew_months = (int16)GB(p1, 16, 16);
   748 				p->engine_renew_money = (uint32)p2;
   755 				p->engine_renew_money = (uint32)p2;
   749 
   756 
   750 				if (IsLocalPlayer()) {
   757 				if (IsLocalPlayer()) {
   751 					_patches.autorenew = p->engine_renew;
   758 					_patches.autorenew = p->engine_renew;
   754 					InvalidateWindow(WC_GAME_OPTIONS, 0);
   761 					InvalidateWindow(WC_GAME_OPTIONS, 0);
   755 				}
   762 				}
   756 			}
   763 			}
   757 			break;
   764 			break;
   758 		case 5:
   765 		case 5:
   759 			if (p->renew_keep_length == (bool)GB(p2, 0, 1))
   766 			if (p->renew_keep_length == HasBit(p2, 0))
   760 				return CMD_ERROR;
   767 				return CMD_ERROR;
   761 
   768 
   762 			if (flags & DC_EXEC) {
   769 			if (flags & DC_EXEC) {
   763 				p->renew_keep_length = (bool)GB(p2, 0, 1);
   770 				p->renew_keep_length = HasBit(p2, 0);
   764 				if (IsLocalPlayer()) {
   771 				if (IsLocalPlayer()) {
   765 					InvalidateWindow(WC_REPLACE_VEHICLE, VEH_TRAIN);
   772 					InvalidateWindow(WC_REPLACE_VEHICLE, VEH_TRAIN);
   766 				}
   773 				}
   767 			}
   774 			}
   768 		break;
   775 		break;
   839 
   846 
   840 		/* This is the joining client who wants a new company */
   847 		/* This is the joining client who wants a new company */
   841 		if (_local_player != _network_playas && _network_playas == p->index) {
   848 		if (_local_player != _network_playas && _network_playas == p->index) {
   842 			assert(_local_player == PLAYER_SPECTATOR);
   849 			assert(_local_player == PLAYER_SPECTATOR);
   843 			SetLocalPlayer(p->index);
   850 			SetLocalPlayer(p->index);
       
   851 			if (!StrEmpty(_network_default_company_pass)) {
       
   852 				char *password = _network_default_company_pass;
       
   853 				NetworkChangeCompanyPassword(1, &password);
       
   854 			}
   844 			MarkWholeScreenDirty();
   855 			MarkWholeScreenDirty();
   845 		}
   856 		}
   846 
   857 
   847 		/* Now that we have a new player, broadcast its autorenew settings to
   858 		/* Now that we have a new player, broadcast its autorenew settings to
   848 		 * all clients so everything is in sync */
   859 		 * all clients so everything is in sync */