src/station_cmd.cpp
branchNewGRF_ports
changeset 6745 f45a41940079
parent 6743 cabfaa4a0295
child 6746 837a9ca5a2f0
equal deleted inserted replaced
6744:e7bf3233928b 6745:f45a41940079
  1514 	}
  1514 	}
  1515 
  1515 
  1516 	return ret;
  1516 	return ret;
  1517 }
  1517 }
  1518 
  1518 
  1519 static void GetFSMportsLayout(byte *layout, int width, int length, const FSMportsSpec *fsmportspec)
  1519 static void GetFSMportsLayout(byte *layout, int width, int length, const FSMportsSpec *fsmportspec, byte set)
  1520 {
  1520 {
  1521 	if (fsmportspec != NULL) {
  1521 	if (fsmportspec != NULL) {
  1522 		/* Custom layout defined, follow it. */
  1522 		/* Custom layout defined, follow it. */
  1523 		memcpy(layout, fsmportspec->layouts[width - 1][length - 1],
  1523 		memcpy(layout, fsmportspec->layouts[set],
  1524 			length * width);
  1524 			(length * width) + 2);  // width*length sprites, plus orientation byte, and preview minipic sprite
  1525 		return;
  1525 		return;
  1526 	}
  1526 	}
  1527 
  1527 
  1528 	while (--width >= 0) {
  1528 	while (--width >= 0) {
  1529 		layout = CreateMulti(layout, length, 4);
  1529 		layout = CreateMulti(layout, length, 4);
  1533 
  1533 
  1534 /** Place an Airport.
  1534 /** Place an Airport.
  1535  * @param tile tile where airport will be built
  1535  * @param tile tile where airport will be built
  1536  * @param flags operation to perform
  1536  * @param flags operation to perform
  1537  * @param p1 various bitstuffed elements
  1537  * @param p1 various bitstuffed elements
  1538  * - p1 = (bit  0)    - orientation (Axis)
  1538  * - p1 = (bit  0-2)  - layout_set for newgrf
  1539  * - p1 = (bit  8-15) - length
  1539  * - p1 = (bit  8-15) - length
  1540  * - p1 = (bit 16-23) - width
  1540  * - p1 = (bit 16-23) - width
  1541  * - p1 = (bit 24)    - allow stations directly adjacent to other stations.
  1541  * - p1 = (bit 24)    - allow stations directly adjacent to other stations.
  1542  * @param p2 various bitstuffed elements
  1542  * @param p2 various bitstuffed elements
  1543  * - p2 = (bit  0- 3) - airport type
  1543  * - p2 = (bit  0- 3) - airport type
  1549 {
  1549 {
  1550 	bool airport_upgrade = true;
  1550 	bool airport_upgrade = true;
  1551 	const uint airport_type_for_flat_check = 0x80 | (GB(p2, 0, 4) << 3);
  1551 	const uint airport_type_for_flat_check = 0x80 | (GB(p2, 0, 4) << 3);
  1552 	bool newfsmairport = (HASBIT(p2, 7));
  1552 	bool newfsmairport = (HASBIT(p2, 7));
  1553 	byte original_airport_type = GB(p2, 0, 4);
  1553 	byte original_airport_type = GB(p2, 0, 4);
       
  1554 	byte layout_set = GB(p1, 0, 3);
  1554 
  1555 
  1555 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
  1556 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
  1556 
  1557 
  1557 	/* Check if a valid, buildable airport was chosen for construction */
  1558 	/* Check if a valid, buildable airport was chosen for construction */
  1558 	//if (p1 > lengthof(_airport_sections) || !HASBIT(GetValidAirports(), p1)) return CMD_ERROR;
  1559 	//if (p1 > lengthof(_airport_sections) || !HASBIT(GetValidAirports(), p1)) return CMD_ERROR;
  1575 			return_cmd_error(STR_2035_LOCAL_AUTHORITY_REFUSES);
  1576 			return_cmd_error(STR_2035_LOCAL_AUTHORITY_REFUSES);
  1576 		}
  1577 		}
  1577 	}
  1578 	}
  1578 
  1579 
  1579 	const AirportFTAClass *afc = GetAirport(original_airport_type);
  1580 	const AirportFTAClass *afc = GetAirport(original_airport_type);
  1580 	int w = afc->size_x;
  1581 	byte w = afc->size_x;
  1581 	int h = afc->size_y;
  1582 	byte h = afc->size_y;
  1582 
  1583 
  1583 	Station *st = NULL;
  1584 	Station *st = NULL;
  1584 
  1585 
  1585 	/* Check if the given station class is valid */
  1586 	/* Check if the given station class is valid */
  1586 	if (GB(p2, 8, 8) >= FSMPORTS_CLASS_MAX) return CMD_ERROR;
  1587 	if (GB(p2, 8, 8) >= FSMPORTS_CLASS_MAX) return CMD_ERROR;
  1588 	/* Check if we can allocate a custom stationspec to this station */
  1589 	/* Check if we can allocate a custom stationspec to this station */
  1589 	const FSMportsSpec *fsmportsspec = GetCustomFSMportsSpec((FSMportsClassID)GB(p2, 8, 8), GB(p2, 16, 8));
  1590 	const FSMportsSpec *fsmportsspec = GetCustomFSMportsSpec((FSMportsClassID)GB(p2, 8, 8), GB(p2, 16, 8));
  1590 
  1591 
  1591 	if (newfsmairport) {
  1592 	if (newfsmairport) {
  1592 		/* Perform NewStation checks */
  1593 		/* Perform NewStation checks */
  1593 		w = fsmportsspec->width;
  1594 		w = fsmportsspec->size_x[layout_set];
  1594 		h = fsmportsspec->lengths;
  1595 		h = fsmportsspec->size_y[layout_set];
  1595 
  1596 
  1596 		/* Check if the station is buildable */
  1597 		/* Check if the station is buildable */
  1597 		if (HASBIT(fsmportsspec->callbackmask, CBM_STATION_AVAIL) && GetFSMportsCallback(CBID_STATION_AVAILABILITY, 0, 0, fsmportsspec, NULL, INVALID_TILE) == 0) {
  1598 		if (HASBIT(fsmportsspec->callbackmask, CBM_STATION_AVAIL) && GetFSMportsCallback(CBID_STATION_AVAILABILITY, 0, 0, fsmportsspec, NULL, INVALID_TILE) == 0) {
  1598 			return CMD_ERROR;
  1599 			return CMD_ERROR;
  1599 		}
  1600 		}
  1663 
  1664 
  1664 		st->airport_tile = tile;
  1665 		st->airport_tile = tile;
  1665 		st->AddFacility(FACIL_AIRPORT, tile);
  1666 		st->AddFacility(FACIL_AIRPORT, tile);
  1666 		st->airport_type = (byte)original_airport_type;
  1667 		st->airport_type = (byte)original_airport_type;
  1667 		st->airport_flags.ResetAll();
  1668 		st->airport_flags.ResetAll();
       
  1669 		st->FSMport_layout_set = layout_set;
  1668 
  1670 
  1669 		st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY);
  1671 		st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY);
  1670 
  1672 
  1671 		/* if airport was demolished while planes were en-route to it, the
  1673 		/* if airport was demolished while planes were en-route to it, the
  1672 		 * positions can no longer be the same (v->u.air.pos), since different
  1674 		 * positions can no longer be the same (v->u.air.pos), since different
  1679 
  1681 
  1680 		if (newfsmairport) {
  1682 		if (newfsmairport) {
  1681 			fsmportspecindex = AllocateFSMportsSpecToStation(fsmportsspec, st, flags & DC_EXEC);
  1683 			fsmportspecindex = AllocateFSMportsSpecToStation(fsmportsspec, st, flags & DC_EXEC);
  1682 			if (fsmportspecindex == -1) return CMD_ERROR;
  1684 			if (fsmportspecindex == -1) return CMD_ERROR;
  1683 
  1685 
  1684 			layout_ptr = (byte*)alloca(w * h);
  1686 			layout_ptr = (byte*)alloca((w * h) + 2);
  1685 			GetFSMportsLayout(layout_ptr, w, h, fsmportsspec);
  1687 			GetFSMportsLayout(layout_ptr, w, h, fsmportsspec, layout_set);
       
  1688 			layout_ptr++; //skip orientation
       
  1689 			layout_ptr++; //skip minipic ID
  1686 		} else {
  1690 		} else {
  1687 			layout_ptr = (byte*)_airport_sections[original_airport_type];
  1691 			layout_ptr = (byte*)_airport_sections[original_airport_type];
  1688 		}
  1692 		}
  1689 
  1693 
  1690 		{
  1694 		{
  1711 static CommandCost RemoveAirport(Station *st, uint32 flags)
  1715 static CommandCost RemoveAirport(Station *st, uint32 flags)
  1712 {
  1716 {
  1713 	int w, h;
  1717 	int w, h;
  1714 	const FSMportsSpec *fsmportsspec;
  1718 	const FSMportsSpec *fsmportsspec;
  1715 	const AirportFTAClass *afc;
  1719 	const AirportFTAClass *afc;
       
  1720 	byte layout_set = st->FSMport_layout_set;
  1716 
  1721 
  1717 	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
  1722 	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
  1718 		return CMD_ERROR;
  1723 		return CMD_ERROR;
  1719 
  1724 
  1720 	TileIndex tile = st->airport_tile;
  1725 	TileIndex tile = st->airport_tile;
  1721 	bool newfsmairport = IsCustomFSMportsSpecIndex(tile);
  1726 	bool newfsmairport = IsCustomFSMportsSpecIndex(tile);
  1722 
  1727 
  1723 	if (newfsmairport) {
  1728 	if (newfsmairport) {
  1724 		fsmportsspec = st->fsmportsspeclist[GetCustomStationSpecIndex(tile)].spec;
  1729 		fsmportsspec = st->fsmportsspeclist[GetCustomStationSpecIndex(tile)].spec;
  1725 		w = fsmportsspec->width;
  1730 		w = fsmportsspec->size_x[layout_set];
  1726 		h = fsmportsspec->lengths;
  1731 		h = fsmportsspec->size_y[layout_set];
  1727 	} else {
  1732 	} else {
  1728 		afc = st->Airport();
  1733 		afc = st->Airport();
  1729 		w = afc->size_x;
  1734 		w = afc->size_x;
  1730 		h = afc->size_y;
  1735 		h = afc->size_y;
  1731 	}
  1736 	}
  1741 
  1746 
  1742 	byte *layout_ptr;
  1747 	byte *layout_ptr;
  1743 	byte layout;
  1748 	byte layout;
  1744 
  1749 
  1745 	if (newfsmairport) {
  1750 	if (newfsmairport) {
  1746 		layout_ptr = (byte*)alloca(w * h);
  1751 		layout_ptr = (byte*)alloca((w * h) + 2);
  1747 		GetFSMportsLayout(layout_ptr, w, h, fsmportsspec);
  1752 		GetFSMportsLayout(layout_ptr, w, h, fsmportsspec, layout_set);
       
  1753 		layout_ptr++; //skip orientation
       
  1754 		layout_ptr++; //skip minipic ID
  1748 	} else {
  1755 	} else {
  1749 		layout_ptr = (byte*)_airport_sections[st->airport_type];
  1756 		layout_ptr = (byte*)_airport_sections[st->airport_type];
  1750 	}
  1757 	}
  1751 
  1758 
  1752 	{
  1759 	{