water_cmd.c
changeset 193 0a7025304867
parent 168 79f9ed5b23e6
child 222 b88456001397
equal deleted inserted replaced
192:614bba52258d 193:0a7025304867
    25  */
    25  */
    26 
    26 
    27 int32 CmdBuildShipDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
    27 int32 CmdBuildShipDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
    28 {
    28 {
    29 	uint tile, tile2;
    29 	uint tile, tile2;
    30 	
    30 
    31 	int32 cost, ret;
    31 	int32 cost, ret;
    32 	Depot *dep;
    32 	Depot *dep;
    33 
    33 
    34 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
    34 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
    35 
    35 
    47 	ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
    47 	ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
    48 	if (ret == CMD_ERROR) return CMD_ERROR;
    48 	if (ret == CMD_ERROR) return CMD_ERROR;
    49 	ret = DoCommandByTile(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
    49 	ret = DoCommandByTile(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
    50 	if (ret == CMD_ERROR)
    50 	if (ret == CMD_ERROR)
    51 		return CMD_ERROR;
    51 		return CMD_ERROR;
    52 	
    52 
    53 	// pretend that we're not making land from the water even though we actually are.
    53 	// pretend that we're not making land from the water even though we actually are.
    54 	cost = 0;
    54 	cost = 0;
    55 
    55 
    56 	dep = AllocateDepot();
    56 	dep = AllocateDepot();
    57 	if (dep == NULL)
    57 	if (dep == NULL)
    60 	if (flags & DC_EXEC) {
    60 	if (flags & DC_EXEC) {
    61 		dep->xy = tile;
    61 		dep->xy = tile;
    62 		_last_built_ship_depot_tile = tile;
    62 		_last_built_ship_depot_tile = tile;
    63 		dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
    63 		dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
    64 
    64 
    65 		ModifyTile(tile, 
    65 		ModifyTile(tile,
    66 			MP_SETTYPE(MP_WATER) | MP_MAPOWNER_CURRENT | MP_MAP5 | MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR,
    66 			MP_SETTYPE(MP_WATER) | MP_MAPOWNER_CURRENT | MP_MAP5 | MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR,
    67 			(0x80 + p1*2)
    67 			(0x80 + p1*2)
    68 		);
    68 		);
    69 	
    69 
    70 		ModifyTile(tile2, 
    70 		ModifyTile(tile2,
    71 			MP_SETTYPE(MP_WATER) | MP_MAPOWNER_CURRENT | MP_MAP5 | MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR,
    71 			MP_SETTYPE(MP_WATER) | MP_MAPOWNER_CURRENT | MP_MAP5 | MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR,
    72 			(0x81 + p1*2)
    72 			(0x81 + p1*2)
    73 		);
    73 		);
    74 	}
    74 	}
    75 
    75 
    99 		ModifyTile(tile2, MP_SETTYPE(MP_WATER) | MP_MAPOWNER | MP_MAP5 | MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR, OWNER_WATER, 0);
    99 		ModifyTile(tile2, MP_SETTYPE(MP_WATER) | MP_MAPOWNER | MP_MAP5 | MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR, OWNER_WATER, 0);
   100 
   100 
   101 		// Kill the entry from the depot table
   101 		// Kill the entry from the depot table
   102 		for(d=_depots; d->xy != tile; d++) {}
   102 		for(d=_depots; d->xy != tile; d++) {}
   103 		d->xy = 0;
   103 		d->xy = 0;
   104 				
   104 
   105 		DeleteWindowById(WC_VEHICLE_DEPOT, tile);		
   105 		DeleteWindowById(WC_VEHICLE_DEPOT, tile);
   106 	}
   106 	}
   107 
   107 
   108 	return _price.remove_ship_depot;
   108 	return _price.remove_ship_depot;
   109 }
   109 }
   110 
   110 
   115 	int delta;
   115 	int delta;
   116 
   116 
   117 	// middle tile
   117 	// middle tile
   118 	ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   118 	ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   119 	if (ret == CMD_ERROR) return CMD_ERROR;
   119 	if (ret == CMD_ERROR) return CMD_ERROR;
   120 	
   120 
   121 	delta = _tileoffs_by_dir[dir];
   121 	delta = _tileoffs_by_dir[dir];
   122 	// lower tile
   122 	// lower tile
   123 	ret = DoCommandByTile(tile - delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   123 	ret = DoCommandByTile(tile - delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   124 	if (ret == CMD_ERROR) return CMD_ERROR;
   124 	if (ret == CMD_ERROR) return CMD_ERROR;
   125 	if (GetTileSlope(tile - delta, NULL)) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   125 	if (GetTileSlope(tile - delta, NULL)) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   149 	if (flags & DC_EXEC) {
   149 	if (flags & DC_EXEC) {
   150 		DoClearSquare(tile);
   150 		DoClearSquare(tile);
   151 		DoClearSquare(tile + delta);
   151 		DoClearSquare(tile + delta);
   152 		DoClearSquare(tile - delta);
   152 		DoClearSquare(tile - delta);
   153 	}
   153 	}
   154 	
   154 
   155 	return _price.clear_water * 2;
   155 	return _price.clear_water * 2;
   156 }
   156 }
   157 
   157 
   158 static void MarkTilesAroundDirty(uint tile)
   158 static void MarkTilesAroundDirty(uint tile)
   159 {
   159 {
   166 int32 CmdBuildLock(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   166 int32 CmdBuildLock(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   167 {
   167 {
   168 	uint tile = TILE_FROM_XY(x,y);
   168 	uint tile = TILE_FROM_XY(x,y);
   169 	int32 ret;
   169 	int32 ret;
   170 	uint th;
   170 	uint th;
   171 	th = GetTileSlope(tile, NULL); 
   171 	th = GetTileSlope(tile, NULL);
   172 
   172 
   173 	if (th==3 || th==6 || th==9 || th==12) {
   173 	if (th==3 || th==6 || th==9 || th==12) {
   174 		static const byte _shiplift_dirs[16] = {0,0,0,2,0,0,1,0,0,3,0,0,0};
   174 		static const byte _shiplift_dirs[16] = {0,0,0,2,0,0,1,0,0,3,0,0,0};
   175 		ret = DoBuildShiplift(tile, _shiplift_dirs[th], flags);
   175 		ret = DoBuildShiplift(tile, _shiplift_dirs[th], flags);
   176 		return ret;
   176 		return ret;
   192 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   192 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   193 
   193 
   194 	// move in which direction?
   194 	// move in which direction?
   195 	delta = (GET_TILE_X(tile) == GET_TILE_X(endtile)) ? TILE_XY(0,1) : TILE_XY(1,0);
   195 	delta = (GET_TILE_X(tile) == GET_TILE_X(endtile)) ? TILE_XY(0,1) : TILE_XY(1,0);
   196 	if (endtile < tile) delta = -delta;
   196 	if (endtile < tile) delta = -delta;
   197 	
   197 
   198 	cost = 0;
   198 	cost = 0;
   199 	for(;;) {
   199 	for(;;) {
   200 		ret = 0;
   200 		ret = 0;
   201 		th = GetTileSlope(tile, NULL);
   201 		th = GetTileSlope(tile, NULL);
   202 		if(th!=0)
   202 		if(th!=0)
   275 			if (slope == 8 || slope == 4 || slope == 2 || slope == 1) {
   275 			if (slope == 8 || slope == 4 || slope == 2 || slope == 1) {
   276 				if (flags & DC_EXEC)
   276 				if (flags & DC_EXEC)
   277 					DoClearSquare(tile);
   277 					DoClearSquare(tile);
   278 				return _price.clear_water;
   278 				return _price.clear_water;
   279 			}
   279 			}
   280 			if (flags & DC_EXEC)			
   280 			if (flags & DC_EXEC)
   281 				DoClearSquare(tile);
   281 				DoClearSquare(tile);
   282 			return _price.purchase_land;
   282 			return _price.purchase_land;
   283 		} else
   283 		} else
   284 			return CMD_ERROR;
   284 			return CMD_ERROR;
   285 	} else if ((m5 & 0x10) == 0x10) {
   285 	} else if ((m5 & 0x10) == 0x10) {
   288 		static const TileIndexDiff _shiplift_tomiddle_offs[12] = {
   288 		static const TileIndexDiff _shiplift_tomiddle_offs[12] = {
   289 			0,0,0,0, // middle
   289 			0,0,0,0, // middle
   290 			TILE_XY(-1, 0),TILE_XY(0, 1),TILE_XY(1, 0),TILE_XY(0, -1), // lower
   290 			TILE_XY(-1, 0),TILE_XY(0, 1),TILE_XY(1, 0),TILE_XY(0, -1), // lower
   291 			TILE_XY(1, 0),TILE_XY(0, -1),TILE_XY(-1, 0),TILE_XY(0, 1), // upper
   291 			TILE_XY(1, 0),TILE_XY(0, -1),TILE_XY(-1, 0),TILE_XY(0, 1), // upper
   292 		};
   292 		};
   293 				
   293 
   294 		if (flags & DC_AUTO) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
   294 		if (flags & DC_AUTO) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
   295 		// don't allow water to delete it.
   295 		// don't allow water to delete it.
   296 		if (_current_player == OWNER_WATER) return CMD_ERROR;
   296 		if (_current_player == OWNER_WATER) return CMD_ERROR;
   297 		// move to the middle tile..
   297 		// move to the middle tile..
   298 		return RemoveShiplift(tile + _shiplift_tomiddle_offs[m5 & 0xF], flags);
   298 		return RemoveShiplift(tile + _shiplift_tomiddle_offs[m5 & 0xF], flags);
   314 // return true if a tile is a water tile.
   314 // return true if a tile is a water tile.
   315 static bool IsWateredTile(uint tile)
   315 static bool IsWateredTile(uint tile)
   316 {
   316 {
   317 	byte m5 = _map5[tile];
   317 	byte m5 = _map5[tile];
   318 	if (IS_TILETYPE(tile, MP_WATER)) {
   318 	if (IS_TILETYPE(tile, MP_WATER)) {
   319 		return m5 != 1;	
   319 		return m5 != 1;
   320 	} else if (IS_TILETYPE(tile, MP_STATION)) {
   320 	} else if (IS_TILETYPE(tile, MP_STATION)) {
   321 		// returns true if it is a dock-station (m5 inside values is m5<75 all stations, 
   321 		// returns true if it is a dock-station (m5 inside values is m5<75 all stations,
   322 		// 83<=m5<=114 new airports
   322 		// 83<=m5<=114 new airports
   323 		return !(m5 < 75 || (m5 >= 83 && m5 <= 114));
   323 		return !(m5 < 75 || (m5 >= 83 && m5 <= 114));
   324 	} else if (IS_TILETYPE(tile, MP_TUNNELBRIDGE)) {
   324 	} else if (IS_TILETYPE(tile, MP_TUNNELBRIDGE)) {
   325 		return (m5 & 0xF8) == 0xC8;
   325 		return (m5 & 0xF8) == 0xC8;
   326 	} else
   326 	} else
   329 
   329 
   330 // draw a canal styled water tile with dikes around
   330 // draw a canal styled water tile with dikes around
   331 void DrawCanalWater(uint tile)
   331 void DrawCanalWater(uint tile)
   332 {
   332 {
   333 	uint wa;
   333 	uint wa;
   334 	
   334 
   335 	// determine the edges around with water.
   335 	// determine the edges around with water.
   336 	wa = IsWateredTile(TILE_ADDXY(tile, -1, 0)) << 0;
   336 	wa = IsWateredTile(TILE_ADDXY(tile, -1, 0)) << 0;
   337 	wa += IsWateredTile(TILE_ADDXY(tile, 0, 1)) << 1;
   337 	wa += IsWateredTile(TILE_ADDXY(tile, 0, 1)) << 1;
   338 	wa += IsWateredTile(TILE_ADDXY(tile, 1, 0)) << 2;
   338 	wa += IsWateredTile(TILE_ADDXY(tile, 1, 0)) << 2;
   339 	wa += IsWateredTile(TILE_ADDXY(tile, 0, -1)) << 3;
   339 	wa += IsWateredTile(TILE_ADDXY(tile, 0, -1)) << 3;
   340 	
   340 
   341 	if (!(wa & 1)) DrawGroundSprite(SPR_CANALS_BASE + 57);
   341 	if (!(wa & 1)) DrawGroundSprite(SPR_CANALS_BASE + 57);
   342 	if (!(wa & 2)) DrawGroundSprite(SPR_CANALS_BASE + 58);
   342 	if (!(wa & 2)) DrawGroundSprite(SPR_CANALS_BASE + 58);
   343 	if (!(wa & 4)) DrawGroundSprite(SPR_CANALS_BASE + 59);
   343 	if (!(wa & 4)) DrawGroundSprite(SPR_CANALS_BASE + 59);
   344 	if (!(wa & 8)) DrawGroundSprite(SPR_CANALS_BASE + 60);
   344 	if (!(wa & 8)) DrawGroundSprite(SPR_CANALS_BASE + 60);
   345 
   345 
   381 static void DrawWaterStuff(TileInfo *ti, const byte *t, uint32 palette, uint base)
   381 static void DrawWaterStuff(TileInfo *ti, const byte *t, uint32 palette, uint base)
   382 {
   382 {
   383 	const WaterDrawTileStruct *wdts;
   383 	const WaterDrawTileStruct *wdts;
   384 	uint32 image;
   384 	uint32 image;
   385 
   385 
   386 	DrawGroundSprite(*(uint16*)t);	
   386 	DrawGroundSprite(*(uint16*)t);
   387 	t += sizeof(uint16);
   387 	t += sizeof(uint16);
   388 		
   388 
   389 	for(wdts = (WaterDrawTileStruct *)t; (byte)wdts->delta_x != 0x80; wdts++) {
   389 	for(wdts = (WaterDrawTileStruct *)t; (byte)wdts->delta_x != 0x80; wdts++) {
   390 		image =	wdts->image + base;
   390 		image =	wdts->image + base;
   391 		if (_display_opt & DO_TRANS_BUILDINGS) {
   391 		if (_display_opt & DO_TRANS_BUILDINGS) {
   392 			image |= palette;
   392 			image |= palette;
   393 		} else {
   393 		} else {
   429 	const WaterDrawTileStruct *wdts;
   429 	const WaterDrawTileStruct *wdts;
   430 
   430 
   431 	t = _shipdepot_display_seq[image];
   431 	t = _shipdepot_display_seq[image];
   432 	DrawSprite(*(uint16*)t, x, y);
   432 	DrawSprite(*(uint16*)t, x, y);
   433 	t += sizeof(uint16);
   433 	t += sizeof(uint16);
   434 		
   434 
   435 	for(wdts = (WaterDrawTileStruct *)t; (byte)wdts->delta_x != 0x80; wdts++) {
   435 	for(wdts = (WaterDrawTileStruct *)t; (byte)wdts->delta_x != 0x80; wdts++) {
   436 		Point pt = RemapCoords(wdts->delta_x, wdts->delta_y, wdts->delta_z);
   436 		Point pt = RemapCoords(wdts->delta_x, wdts->delta_y, wdts->delta_z);
   437 		DrawSprite(wdts->image + PLAYER_SPRITE_COLOR(_local_player), x + pt.x, y + pt.y);
   437 		DrawSprite(wdts->image + PLAYER_SPRITE_COLOR(_local_player), x + pt.x, y + pt.y);
   438 	}
   438 	}
   439 }
   439 }
   440 
   440 
   441 
   441 
   442 uint GetSlopeZ_Water(TileInfo *ti)
   442 uint GetSlopeZ_Water(TileInfo *ti)
   443 { 
   443 {
   444 	return GetPartialZ(ti->x&0xF, ti->y&0xF, ti->tileh) + ti->z;
   444 	return GetPartialZ(ti->x&0xF, ti->y&0xF, ti->tileh) + ti->z;
   445 }
   445 }
   446 
   446 
   447 uint GetSlopeTileh_Water(TileInfo *ti)
   447 uint GetSlopeTileh_Water(TileInfo *ti)
   448 { 
   448 {
   449 	return ti->tileh;
   449 	return ti->tileh;
   450 }
   450 }
   451 
   451 
   452 static void GetAcceptedCargo_Water(uint tile, AcceptedCargo *ac)
   452 static void GetAcceptedCargo_Water(uint tile, AcceptedCargo *ac)
   453 {
   453 {
   532 			v->vehstatus |= VS_CRASHED;
   532 			v->vehstatus |= VS_CRASHED;
   533 			v->u.road.crashed_ctr = 2000;	// max 2220, disappear pretty fast
   533 			v->u.road.crashed_ctr = 2000;	// max 2220, disappear pretty fast
   534 			_vehicle_sort_dirty[VEHROAD] = true;
   534 			_vehicle_sort_dirty[VEHROAD] = true;
   535 			InvalidateWindow(WC_ROADVEH_LIST, v->owner);
   535 			InvalidateWindow(WC_ROADVEH_LIST, v->owner);
   536 		}
   536 		}
   537 		
   537 
   538 		else if (v->type == VEH_Train) {
   538 		else if (v->type == VEH_Train) {
   539 			v = GetFirstVehicleInChain(v);
   539 			v = GetFirstVehicleInChain(v);
   540 			u = v;
   540 			u = v;
   541 			pass = 4;	// driver
   541 			pass = 4;	// driver
   542 
   542 
   547 			END_ENUM_WAGONS(v)
   547 			END_ENUM_WAGONS(v)
   548 
   548 
   549 			v = u;
   549 			v = u;
   550 			v->u.rail.crash_anim_pos = 4000; // max 4440, disappear pretty fast
   550 			v->u.rail.crash_anim_pos = 4000; // max 4440, disappear pretty fast
   551 			_vehicle_sort_dirty[VEHTRAIN] = true;
   551 			_vehicle_sort_dirty[VEHTRAIN] = true;
   552 			InvalidateWindow(WC_TRAINS_LIST, v->owner);						
   552 			InvalidateWindow(WC_TRAINS_LIST, v->owner);
   553 		} else
   553 		} else
   554 			return;
   554 			return;
   555 
   555 
   556 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   556 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   557 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   557 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   558 		
   558 
   559 		SET_DPARAM16(0, pass);
   559 		SET_DPARAM16(0, pass);
   560 		AddNewsItem(STR_B006_FLOOD_VEHICLE_DESTROYED,
   560 		AddNewsItem(STR_B006_FLOOD_VEHICLE_DESTROYED,
   561 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
   561 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
   562 			v->index,
   562 			v->index,
   563 			0);
   563 			0);
   619 		b = _coast_tracks[GetTileSlope(tile, NULL)&0xF];
   619 		b = _coast_tracks[GetTileSlope(tile, NULL)&0xF];
   620 		return b + (b<<8);
   620 		return b + (b<<8);
   621 	}
   621 	}
   622 
   622 
   623 	if ( (m5 & 0x10) == 0x10) {
   623 	if ( (m5 & 0x10) == 0x10) {
   624 		// 
   624 		//
   625 		b = _shiplift_tracks[m5 & 0xF];
   625 		b = _shiplift_tracks[m5 & 0xF];
   626 		return b + (b<<8);
   626 		return b + (b<<8);
   627 	}
   627 	}
   628 
   628 
   629 	if (!(m5 & 0x80))
   629 	if (!(m5 & 0x80))
   636 extern void ShowShipDepotWindow(uint tile);
   636 extern void ShowShipDepotWindow(uint tile);
   637 
   637 
   638 static void ClickTile_Water(uint tile)
   638 static void ClickTile_Water(uint tile)
   639 {
   639 {
   640 	byte m5 = _map5[tile] - 0x80;
   640 	byte m5 = _map5[tile] - 0x80;
   641 	
   641 
   642 	if (IS_BYTE_INSIDE(m5, 0, 3+1)) {
   642 	if (IS_BYTE_INSIDE(m5, 0, 3+1)) {
   643 		if (m5 & 1)
   643 		if (m5 & 1)
   644 			tile += (m5==1) ? TILE_XY(-1,0) : TILE_XY(0,-1);
   644 			tile += (m5==1) ? TILE_XY(-1,0) : TILE_XY(0,-1);
   645 		ShowShipDepotWindow(tile);
   645 		ShowShipDepotWindow(tile);
   646 	}
   646 	}