コード例 #1
0
TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
	const char *exp, const char *file, int line)
{
	int dx;
	int dy;
	uint x;
	uint y;

	dx = add & MapMaxX();
	if (dx >= (int)MapSizeX() / 2) dx -= MapSizeX();
	dy = (add - dx) / (int)MapSizeX();

	x = TileX(tile) + dx;
	y = TileY(tile) + dy;

	if (x >= MapSizeX() || y >= MapSizeY()) {
		char buf[512];

		snprintf(buf, lengthof(buf), "TILE_ADD(%s) when adding 0x%.4X and 0x%.4X failed",
			exp, tile, add);
#if !defined(_MSC_VER) || defined(WINCE)
		fprintf(stderr, "%s:%d %s\n", file, line, buf);
#else
		_assert(buf, (char*)file, line);
#endif
	}

	assert(TileXY(x, y) == TILE_MASK(tile + add));

	return TileXY(x, y);
}
コード例 #2
0
static void TPFModeShip(TrackPathFinder *tpf, TileIndex tile, DiagDirection direction)
{
    if (IsTileType(tile, MP_TUNNELBRIDGE)) {
        /* wrong track type */
        if (GetTunnelBridgeTransportType(tile) != TRANSPORT_WATER) return;

        DiagDirection dir = GetTunnelBridgeDirection(tile);
        /* entering tunnel / bridge? */
        if (dir == direction) {
            TileIndex endtile = GetOtherTunnelBridgeEnd(tile);

            tpf->rd.cur_length += GetTunnelBridgeLength(tile, endtile) + 1;

            tile = endtile;
        } else {
            /* leaving tunnel / bridge? */
            if (ReverseDiagDir(dir) != direction) return;
        }
    }

    /* This addition will sometimes overflow by a single tile.
     * The use of TILE_MASK here makes sure that we still point at a valid
     * tile, and then this tile will be in the sentinel row/col, so GetTileTrackStatus will fail. */
    tile = TILE_MASK(tile + TileOffsByDiagDir(direction));

    if (++tpf->rd.cur_length > 50) return;

    TrackBits bits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)) & DiagdirReachesTracks(direction);
    if (bits == TRACK_BIT_NONE) return;

    assert(TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY());

    bool only_one_track = true;
    do {
        Track track = RemoveFirstTrack(&bits);
        if (bits != TRACK_BIT_NONE) only_one_track = false;
        RememberData rd = tpf->rd;

        /* Change direction 4 times only */
        if (!only_one_track && track != tpf->rd.last_choosen_track) {
            if (++tpf->rd.depth > 4) {
                tpf->rd = rd;
                return;
            }
            tpf->rd.last_choosen_track = track;
        }

        tpf->the_dir = TrackEnterdirToTrackdir(track, direction);

        if (!ShipTrackFollower(tile, tpf, tpf->rd.cur_length)) {
            TPFModeShip(tpf, tile, TrackdirToExitdir(tpf->the_dir));
        }

        tpf->rd = rd;
    } while (bits != TRACK_BIT_NONE);
}
コード例 #3
0
/**
 * @note Used by the resolver to get values for feature 07 deterministic spritegroups.
 */
/* virtual */ uint32 HouseScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
{
	switch (variable) {
		/* Construction stage. */
		case 0x40: return (IsTileType(this->tile, MP_HOUSE) ? GetHouseBuildingStage(this->tile) : 0) | TileHash2Bit(TileX(this->tile), TileY(this->tile)) << 2;

		/* Building age. */
		case 0x41: return IsTileType(this->tile, MP_HOUSE) ? GetHouseAge(this->tile) : 0;

		/* Town zone */
		case 0x42: return GetTownRadiusGroup(this->town, this->tile);

		/* Terrain type */
		case 0x43: return GetTerrainType(this->tile);

		/* Number of this type of building on the map. */
		case 0x44: return GetNumHouses(this->house_id, this->town);

		/* Whether the town is being created or just expanded. */
		case 0x45: return _generating_world ? 1 : 0;

		/* Current animation frame. */
		case 0x46: return IsTileType(this->tile, MP_HOUSE) ? GetAnimationFrame(this->tile) : 0;

		/* Position of the house */
		case 0x47: return TileY(this->tile) << 16 | TileX(this->tile);

		/* Building counts for old houses with id = parameter. */
		case 0x60: return parameter < NEW_HOUSE_OFFSET ? GetNumHouses(parameter, this->town) : 0;

		/* Building counts for new houses with id = parameter. */
		case 0x61: {
			const HouseSpec *hs = HouseSpec::Get(this->house_id);
			if (hs->grf_prop.grffile == NULL) return 0;

			HouseID new_house = _house_mngr.GetID(parameter, hs->grf_prop.grffile->grfid);
			return new_house == INVALID_HOUSE_ID ? 0 : GetNumHouses(new_house, this->town);
		}

		/* Land info for nearby tiles. */
		case 0x62: return GetNearbyTileInformation(parameter, this->tile, this->ro->grffile->grf_version >= 8);

		/* Current animation frame of nearby house tiles */
		case 0x63: {
			TileIndex testtile = GetNearbyTile(parameter, this->tile);
			return IsTileType(testtile, MP_HOUSE) ? GetAnimationFrame(testtile) : 0;
		}

		/* Cargo acceptance history of nearby stations */
		case 0x64: {
			CargoID cid = GetCargoTranslation(parameter, this->ro->grffile);
			if (cid == CT_INVALID) return 0;

			/* Extract tile offset. */
			int8 x_offs = GB(GetRegister(0x100), 0, 8);
			int8 y_offs = GB(GetRegister(0x100), 8, 8);
			TileIndex testtile = TILE_MASK(this->tile + TileDiffXY(x_offs, y_offs));

			StationFinder stations(TileArea(testtile, 1, 1));
			const StationList *sl = stations.GetStations();

			/* Collect acceptance stats. */
			uint32 res = 0;
			for (Station * const * st_iter = sl->Begin(); st_iter != sl->End(); st_iter++) {
				const Station *st = *st_iter;
				if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_EVER_ACCEPTED))    SetBit(res, 0);
				if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_LAST_MONTH))       SetBit(res, 1);
				if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_CURRENT_MONTH))    SetBit(res, 2);
				if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_ACCEPTED_BIGTICK)) SetBit(res, 3);
			}

			/* Cargo triggered CB 148? */
			if (HasBit(this->watched_cargo_triggers, cid)) SetBit(res, 4);

			return res;
		}

		/* Distance test for some house types */
		case 0x65: return GetDistanceFromNearbyHouse(parameter, this->tile, this->house_id);

		/* Class and ID of nearby house tile */
		case 0x66: {
			TileIndex testtile = GetNearbyTile(parameter, this->tile);
			if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
			HouseSpec *hs = HouseSpec::Get(GetHouseType(testtile));
			/* Information about the grf local classid if the house has a class */
			uint houseclass = 0;
			if (hs->class_id != HOUSE_NO_CLASS) {
				houseclass = (hs->grf_prop.grffile == this->ro->grffile ? 1 : 2) << 8;
				houseclass |= _class_mapping[hs->class_id].class_id;
			}
			/* old house type or grf-local houseid */
			uint local_houseid = 0;
			if (this->house_id < NEW_HOUSE_OFFSET) {
				local_houseid = this->house_id;
			} else {
				local_houseid = (hs->grf_prop.grffile == this->ro->grffile ? 1 : 2) << 8;
				local_houseid |= hs->grf_prop.local_id;
			}
			return houseclass << 16 | local_houseid;
		}

		/* GRFID of nearby house tile */
		case 0x67: {
			TileIndex testtile = GetNearbyTile(parameter, this->tile);
			if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
			HouseID house_id = GetHouseType(testtile);
			if (house_id < NEW_HOUSE_OFFSET) return 0;
			/* Checking the grffile information via HouseSpec doesn't work
			 * in case the newgrf was removed. */
			return _house_mngr.GetGRFID(house_id);
		}
	}

	DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);

	*available = false;
	return UINT_MAX;
}