(svn r1731) - Fix: [ 1106930 ] BugFix: placing signals with 2x1 drags workaround is completely rewritten. Also features checks for hacked/modified clients. Thanks a lot Hackykid!
This commit is contained in:
		
							
								
								
									
										25
									
								
								command.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								command.c
									
									
									
									
									
								
							@@ -22,8 +22,8 @@ DEF_COMMAND(CmdBuildRailroadStation);
 | 
			
		||||
DEF_COMMAND(CmdRemoveFromRailroadStation);
 | 
			
		||||
DEF_COMMAND(CmdConvertRail);
 | 
			
		||||
 | 
			
		||||
DEF_COMMAND(CmdBuildSignals);
 | 
			
		||||
DEF_COMMAND(CmdRemoveSignals);
 | 
			
		||||
DEF_COMMAND(CmdBuildSingleSignal);
 | 
			
		||||
DEF_COMMAND(CmdRemoveSingleSignal);
 | 
			
		||||
 | 
			
		||||
DEF_COMMAND(CmdTerraformLand);
 | 
			
		||||
 | 
			
		||||
@@ -163,7 +163,8 @@ DEF_COMMAND(CmdRefitRailVehicle);
 | 
			
		||||
 | 
			
		||||
DEF_COMMAND(CmdStartScenario);
 | 
			
		||||
 | 
			
		||||
DEF_COMMAND(CmdBuildManySignals);
 | 
			
		||||
DEF_COMMAND(CmdBuildSignalTrack);
 | 
			
		||||
DEF_COMMAND(CmdRemoveSignalTrack);
 | 
			
		||||
 | 
			
		||||
DEF_COMMAND(CmdReplaceVehicle);
 | 
			
		||||
 | 
			
		||||
@@ -177,8 +178,8 @@ static CommandProc * const _command_proc_table[] = {
 | 
			
		||||
	CmdBuildBridge,								/* 5  */
 | 
			
		||||
	CmdBuildRailroadStation,			/* 6  */
 | 
			
		||||
	CmdBuildTrainDepot,						/* 7  */
 | 
			
		||||
	CmdBuildSignals,							/* 8  */
 | 
			
		||||
	CmdRemoveSignals,							/* 9  */
 | 
			
		||||
	CmdBuildSingleSignal,					/* 8  */
 | 
			
		||||
	CmdRemoveSingleSignal,				/* 9  */
 | 
			
		||||
	CmdTerraformLand,							/* 10 */
 | 
			
		||||
	CmdPurchaseLandArea,					/* 11 */
 | 
			
		||||
	CmdSellLandArea,							/* 12 */
 | 
			
		||||
@@ -302,12 +303,14 @@ static CommandProc * const _command_proc_table[] = {
 | 
			
		||||
	CmdRestoreOrderIndex,					/* 107 */
 | 
			
		||||
	CmdBuildLock,									/* 108 */
 | 
			
		||||
	CmdStartScenario,							/* 109 */
 | 
			
		||||
	CmdBuildManySignals,					/* 110 */
 | 
			
		||||
	//CmdDestroyIndustry,						/* 109 */
 | 
			
		||||
	CmdDestroyCompanyHQ,					/* 111 */
 | 
			
		||||
	CmdGiveMoney,									/* 112 */
 | 
			
		||||
	CmdChangePatchSetting,				/* 113 */
 | 
			
		||||
	CmdReplaceVehicle,							/* 114 */
 | 
			
		||||
	CmdBuildSignalTrack,					/* 110 */
 | 
			
		||||
	CmdRemoveSignalTrack,					/* 111 */
 | 
			
		||||
	CmdDestroyCompanyHQ,					/* 112 */
 | 
			
		||||
	CmdGiveMoney,									/* 113 */
 | 
			
		||||
	CmdChangePatchSetting,				/* 114 */
 | 
			
		||||
	CmdReplaceVehicle,						/* 115 */
 | 
			
		||||
 | 
			
		||||
	//CmdDestroyIndustry,					/* 109 */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* This function range-checks a cmd, and checks if the cmd is not NULL */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								command.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								command.h
									
									
									
									
									
								
							@@ -141,14 +141,15 @@ enum {
 | 
			
		||||
	CMD_BUILD_LOCK = 108,
 | 
			
		||||
 | 
			
		||||
	CMD_START_SCENARIO = 109,
 | 
			
		||||
	CMD_BUILD_MANY_SIGNALS = 110,
 | 
			
		||||
	CMD_BUILD_SIGNAL_TRACK  = 110,
 | 
			
		||||
	CMD_REMOVE_SIGNAL_TRACK = 111,
 | 
			
		||||
 | 
			
		||||
	CMD_DESTROY_COMPANY_HQ = 112,
 | 
			
		||||
	CMD_GIVE_MONEY = 113,
 | 
			
		||||
	CMD_CHANGE_PATCH_SETTING = 114,
 | 
			
		||||
 | 
			
		||||
	CMD_REPLACE_VEHICLE = 115,
 | 
			
		||||
	//CMD_DESTROY_INDUSTRY = 109,
 | 
			
		||||
	CMD_DESTROY_COMPANY_HQ = 111,
 | 
			
		||||
	CMD_GIVE_MONEY = 112,
 | 
			
		||||
	CMD_CHANGE_PATCH_SETTING = 113,
 | 
			
		||||
 | 
			
		||||
	CMD_REPLACE_VEHICLE = 114,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										222
									
								
								rail_cmd.c
									
									
									
									
									
								
							
							
						
						
									
										222
									
								
								rail_cmd.c
									
									
									
									
									
								
							@@ -512,64 +512,99 @@ skip_mark_dirty:;
 | 
			
		||||
static const struct {
 | 
			
		||||
	int8 xinc[16];
 | 
			
		||||
	int8 yinc[16];
 | 
			
		||||
	byte initial[16];
 | 
			
		||||
} _railbit = {{
 | 
			
		||||
//  0   1   2    3   4   5
 | 
			
		||||
	 16,  0,-16,   0, 16,  0,    0,  0,
 | 
			
		||||
	-16,  0,  0,  16,  0,-16,    0,  0,
 | 
			
		||||
//  0   1   2   3   4   5
 | 
			
		||||
	-16,  0,-16,  0, 16,  0,    0,  0,
 | 
			
		||||
	 16,  0,  0, 16,  0,-16,    0,  0,
 | 
			
		||||
},{
 | 
			
		||||
	0,   16,  0,  16,  0, 16,    0,  0,
 | 
			
		||||
	0,  -16, -16,  0,-16,  0,    0,  0,
 | 
			
		||||
},{
 | 
			
		||||
	5,     1,   0,   4, // normal
 | 
			
		||||
	2,     1, 8|0,   3, // x > sx
 | 
			
		||||
	8|2, 8|1,   0, 8|3, // y > sy
 | 
			
		||||
	8|5, 8|1, 8|0, 8|4, // x > sx && y > sy
 | 
			
		||||
	  0, 16,  0, 16,  0, 16,    0,  0,
 | 
			
		||||
	  0,-16,-16,  0,-16,  0,    0,  0,
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Build either NE or NW sequence of tracks.
 | 
			
		||||
 * p1 0:15  - end pt X
 | 
			
		||||
 * p1 16:31 - end pt y
 | 
			
		||||
 *
 | 
			
		||||
 * p2 0:3   - rail type
 | 
			
		||||
 * p2 4:7   - rail direction
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int32 CmdBuildRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
static int32 ValidateAutoDrag(int *railbit, int x, int y, int ex, int ey)
 | 
			
		||||
{
 | 
			
		||||
	int sx, sy;
 | 
			
		||||
	int dx, dy, trdx, trdy;
 | 
			
		||||
 | 
			
		||||
	if (*railbit > 5) return CMD_ERROR; // only 6 possible track-combinations
 | 
			
		||||
 | 
			
		||||
	// calculate delta x,y from start to end tile
 | 
			
		||||
	dx = ex - x;
 | 
			
		||||
	dy = ey - y;
 | 
			
		||||
 | 
			
		||||
	// calculate delta x,y for the first direction
 | 
			
		||||
	trdx = _railbit.xinc[*railbit];
 | 
			
		||||
	trdy = _railbit.yinc[*railbit];
 | 
			
		||||
 | 
			
		||||
	if (*railbit & 0x6) {
 | 
			
		||||
		trdx += _railbit.xinc[*railbit ^ 1];
 | 
			
		||||
		trdy += _railbit.yinc[*railbit ^ 1];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// validate the direction
 | 
			
		||||
	while (((trdx <= 0) && (dx > 0)) || ((trdx >= 0) && (dx < 0)) ||
 | 
			
		||||
	       ((trdy <= 0) && (dy > 0)) || ((trdy >= 0) && (dy < 0))) {
 | 
			
		||||
		if (*railbit < 8) { // first direction is invalid, try the other
 | 
			
		||||
			SETBIT(*railbit, 3);
 | 
			
		||||
			trdx = -trdx;
 | 
			
		||||
			trdy = -trdy;
 | 
			
		||||
		} else // other direction is invalid too, invalid drag
 | 
			
		||||
			return CMD_ERROR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// (for diagonal tracks, this is already made sure of by above test), but:
 | 
			
		||||
	// for non-diagonal tracks, check if the start and end tile are on 1 line
 | 
			
		||||
	if (*railbit & 0x6) {
 | 
			
		||||
		trdx = _railbit.xinc[*railbit];
 | 
			
		||||
		trdy = _railbit.yinc[*railbit];
 | 
			
		||||
		if ((abs(dx) != abs(dy)) && (abs(dx) + abs(trdy) != abs(dy) + abs(trdx)))
 | 
			
		||||
			return CMD_ERROR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Build a stretch of railroad tracks.
 | 
			
		||||
 * x,y= start tile
 | 
			
		||||
 * p1 = end tile
 | 
			
		||||
 * p2 = (bit 0-3)		- railroad type normal/maglev
 | 
			
		||||
 * p2 = (bit 4-6)		- track-orientation, valid values: 0-5
 | 
			
		||||
 * p2 = (bit 7)			- 0 = build, 1 = remove tracks
 | 
			
		||||
 */
 | 
			
		||||
static int32 CmdRailTrackHelper(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
{
 | 
			
		||||
	int ex, ey;
 | 
			
		||||
	int32 ret, total_cost = 0;
 | 
			
		||||
	int railbit;
 | 
			
		||||
	int railbit = (p2 >> 4) & 7;
 | 
			
		||||
	byte mode = HASBIT(p2, 7);
 | 
			
		||||
 | 
			
		||||
	/* unpack end point */
 | 
			
		||||
	ex = TileX(p1) * 16;
 | 
			
		||||
	ey = TileY(p1) * 16;
 | 
			
		||||
 | 
			
		||||
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 | 
			
		||||
 | 
			
		||||
	if (flags & DC_EXEC)
 | 
			
		||||
		SndPlayTileFx(SND_20_SPLAT_2, TILE_FROM_XY(x,y));
 | 
			
		||||
 | 
			
		||||
	/* unpack end point */
 | 
			
		||||
	sx = (p1 & 0xFFFF) & ~0xF;
 | 
			
		||||
	sy = (p1 >> 16) & ~0xF;
 | 
			
		||||
 | 
			
		||||
	railbit = _railbit.initial[(p2 >> 4) + (x > sx ? 4 : 0) + (y > sy ? 8 : 0)];
 | 
			
		||||
	if (ValidateAutoDrag(&railbit, x, y, ex, ey) == CMD_ERROR)
 | 
			
		||||
		return CMD_ERROR;
 | 
			
		||||
 | 
			
		||||
	for(;;) {
 | 
			
		||||
		ret = DoCommand(x, y, p2&0xF, railbit&7, flags, CMD_BUILD_SINGLE_RAIL);
 | 
			
		||||
		ret = DoCommand(x, y, p2&0x3, railbit&7, flags, (mode == 0) ? CMD_BUILD_SINGLE_RAIL : CMD_REMOVE_SINGLE_RAIL);
 | 
			
		||||
 | 
			
		||||
		if (ret == CMD_ERROR) {
 | 
			
		||||
			if (_error_message != STR_1007_ALREADY_BUILT)
 | 
			
		||||
			if ((_error_message != STR_1007_ALREADY_BUILT) && (mode == 0))
 | 
			
		||||
				break;
 | 
			
		||||
		} else
 | 
			
		||||
			total_cost += ret;
 | 
			
		||||
 | 
			
		||||
		if (x == sx && y == sy)
 | 
			
		||||
		if (x == ex && y == ey)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		x += _railbit.xinc[railbit];
 | 
			
		||||
		y += _railbit.yinc[railbit];
 | 
			
		||||
 | 
			
		||||
		// toggle railbit for the diagonal tiles
 | 
			
		||||
		// toggle railbit for the non-diagonal tracks
 | 
			
		||||
		if (railbit & 0x6) railbit ^= 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -579,48 +614,14 @@ int32 CmdBuildRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
	return total_cost;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Remove either NE or NW sequence of tracks.
 | 
			
		||||
 * p1 0:15  - start pt X
 | 
			
		||||
 * p1 16:31 - start pt y
 | 
			
		||||
 *
 | 
			
		||||
 * p2 0:3   - rail type
 | 
			
		||||
 * p2 4:7   - rail direction
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int32 CmdBuildRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
{
 | 
			
		||||
	return CmdRailTrackHelper(x, y, flags, p1, p2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32 CmdRemoveRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
{
 | 
			
		||||
	int sx, sy;
 | 
			
		||||
	int32 ret, total_cost = 0;
 | 
			
		||||
	int railbit;
 | 
			
		||||
 | 
			
		||||
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 | 
			
		||||
 | 
			
		||||
	if (flags & DC_EXEC)
 | 
			
		||||
		SndPlayTileFx(SND_20_SPLAT_2, TILE_FROM_XY(x,y));
 | 
			
		||||
 | 
			
		||||
	/* unpack start point */
 | 
			
		||||
	sx = (p1 & 0xFFFF) & ~0xF;
 | 
			
		||||
	sy = (p1 >> 16) & ~0xF;
 | 
			
		||||
 | 
			
		||||
	railbit = _railbit.initial[(p2 >> 4) + (x > sx ? 4 : 0) + (y > sy ? 8 : 0)];
 | 
			
		||||
 | 
			
		||||
	for(;;) {
 | 
			
		||||
		ret = DoCommand(x, y, p2&0xF, railbit&7, flags, CMD_REMOVE_SINGLE_RAIL);
 | 
			
		||||
		if (ret != CMD_ERROR) total_cost += ret;
 | 
			
		||||
		if (x == sx && y == sy)
 | 
			
		||||
			break;
 | 
			
		||||
		x += _railbit.xinc[railbit];
 | 
			
		||||
		y += _railbit.yinc[railbit];
 | 
			
		||||
		// toggle railbit for the diagonal tiles
 | 
			
		||||
		if (railbit & 0x6) railbit ^= 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (total_cost == 0)
 | 
			
		||||
		return CMD_ERROR;
 | 
			
		||||
 | 
			
		||||
	return total_cost;
 | 
			
		||||
	return CmdRailTrackHelper(x, y, flags, p1, SETBIT(p2, 7));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Build a train depot
 | 
			
		||||
@@ -870,7 +871,7 @@ int32 CmdRenameWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
 *               depending on context
 | 
			
		||||
 * p2 = used for CmdBuildManySignals() to copy style of first signal
 | 
			
		||||
 */
 | 
			
		||||
int32 CmdBuildSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
int32 CmdBuildSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
{
 | 
			
		||||
	TileIndex tile = TILE_FROM_XY(x, y);
 | 
			
		||||
	bool semaphore;
 | 
			
		||||
@@ -992,68 +993,45 @@ int32 CmdBuildSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*	Build many signals by dragging: AutoSignals
 | 
			
		||||
		x,y= start tile
 | 
			
		||||
		p1 = end tile
 | 
			
		||||
		p2 = (byte 0)			- 0 = build, 1 = remove signals
 | 
			
		||||
		p2 = (byte 3)			- 0 = signals, 1 = semaphores
 | 
			
		||||
		p2 = (byte 7-4)		- track-orientation
 | 
			
		||||
		p2 = (byte 8-)		- track style
 | 
			
		||||
		p2 = (byte 24-31)	- user defined signals_density
 | 
			
		||||
 * x,y = start tile
 | 
			
		||||
 * p1  = end tile
 | 
			
		||||
 * p2  = (bit 0)			- 0 = build, 1 = remove signals
 | 
			
		||||
 * p2  = (bit 3)			- 0 = signals, 1 = semaphores
 | 
			
		||||
 * p2  = (bit 4-6)		- track-orientation, valid values: 0-5
 | 
			
		||||
 * p2  = (bit 24-31)	- user defined signals_density
 | 
			
		||||
 */
 | 
			
		||||
int32 CmdBuildManySignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
static int32 CmdSignalTrackHelper(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
{
 | 
			
		||||
	int ex, ey, railbit;
 | 
			
		||||
	int ex, ey;
 | 
			
		||||
	int railbit = (p2 >> 4) & 7;
 | 
			
		||||
	bool error = true;
 | 
			
		||||
	TileIndex tile = TILE_FROM_XY(x, y);
 | 
			
		||||
	int32 ret, total_cost, signal_ctr;
 | 
			
		||||
	byte m5, semaphores = (HASBIT(p2, 3)) ? 8 : 0;
 | 
			
		||||
	int mode = (p2 >> 4)&0xF;
 | 
			
		||||
	int mode = p2 & 0x1;
 | 
			
		||||
	// for vertical/horizontal tracks, double the given signals density
 | 
			
		||||
	// since the original amount will be too dense (shorter tracks)
 | 
			
		||||
	byte signal_density = (mode == 1 || mode == 2) ? (p2 >> 24) : (p2 >> 24) * 2;
 | 
			
		||||
	byte signals = (p2 >> 8)&0xFF;
 | 
			
		||||
	mode = p2 & 0x1;  // build/remove signals
 | 
			
		||||
	byte signal_density = (railbit & 0x6) ? (p2 >> 24) * 2: (p2 >> 24);
 | 
			
		||||
	byte signals;
 | 
			
		||||
 | 
			
		||||
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 | 
			
		||||
 | 
			
		||||
	/* unpack end tile */
 | 
			
		||||
	// unpack end tile
 | 
			
		||||
	ex = TileX(p1) * 16;
 | 
			
		||||
	ey = TileY(p1) * 16;
 | 
			
		||||
 | 
			
		||||
	railbit = _railbit.initial[((p2 >> 4)&0xF) + (x > ex ? 4 : 0) + (y > ey ? 8 : 0)];
 | 
			
		||||
	if (ValidateAutoDrag(&railbit, x, y, ex, ey) == CMD_ERROR)
 | 
			
		||||
		return CMD_ERROR;
 | 
			
		||||
 | 
			
		||||
	// copy the signal-style of the first rail-piece if existing
 | 
			
		||||
	m5 = _map5[tile];
 | 
			
		||||
	if (!(m5 & RAIL_TYPE_SPECIAL) && (m5 & RAIL_BIT_MASK) && (m5 & RAIL_TYPE_SIGNALS)) {
 | 
			
		||||
		if (m5 & 0x3) // X,Y direction tracks
 | 
			
		||||
			signals = _map3_lo[tile]&0xC0;
 | 
			
		||||
		else {
 | 
			
		||||
			/* W-E or N-S direction, only copy the side which was chosen, leave
 | 
			
		||||
			 * the other side alone */
 | 
			
		||||
			switch (signals) {
 | 
			
		||||
				case 0x20: case 8: /* east corner (N-S), south corner (W-E) */
 | 
			
		||||
					if (_map3_lo[tile]&0x30)
 | 
			
		||||
						signals = _map3_lo[tile]&0x30;
 | 
			
		||||
					else
 | 
			
		||||
						signals = 0x30 | (_map3_lo[tile]&0xC0);
 | 
			
		||||
					break;
 | 
			
		||||
				case 0x10: case 4: /* west corner (N-S), north corner (W-E) */
 | 
			
		||||
					if (_map3_lo[tile]&0xC0)
 | 
			
		||||
						signals = _map3_lo[tile]&0xC0;
 | 
			
		||||
					else
 | 
			
		||||
						signals = 0xC0 | (_map3_lo[tile]&0x30);
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		signals = _map3_lo[tile] & _signals_table_both[railbit];
 | 
			
		||||
		if (signals == 0) signals = _signals_table_both[railbit];
 | 
			
		||||
 | 
			
		||||
		semaphores = (_map3_hi[tile] & ~3) ? 8 : 0; // copy signal/semaphores style (independent of CTRL)
 | 
			
		||||
	} else { // no signals exist, drag a two-way signal stretch
 | 
			
		||||
		switch (signals) {
 | 
			
		||||
			case 0x20: case 8: /* east corner (N-S), south corner (W-E) */
 | 
			
		||||
				signals = 0x30; break;
 | 
			
		||||
			case 0x10: case 4: /* west corner (N-S), north corner (W-E) */
 | 
			
		||||
				signals = 0xC0;
 | 
			
		||||
		}
 | 
			
		||||
		signals = _signals_table_both[railbit];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* signal_density_ctr	- amount of tiles already processed
 | 
			
		||||
@@ -1089,19 +1067,25 @@ int32 CmdBuildManySignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
		y += _railbit.yinc[railbit];
 | 
			
		||||
		signal_ctr++;
 | 
			
		||||
 | 
			
		||||
		// toggle railbit for the diagonal tiles (|, -- tracks)
 | 
			
		||||
		// toggle railbit for the non-diagonal tracks (|, -- tracks)
 | 
			
		||||
		if (railbit & 0x6) railbit ^= 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (error) ? CMD_ERROR : total_cost;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Stub for the unified Signal builder/remover */
 | 
			
		||||
int32 CmdBuildSignalTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
{
 | 
			
		||||
	return CmdSignalTrackHelper(x, y, flags, p1, p2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Remove signals
 | 
			
		||||
 * p1 bits 0..2 = track
 | 
			
		||||
 * p2 = unused
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int32 CmdRemoveSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
int32 CmdRemoveSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
{
 | 
			
		||||
	TileInfo ti;
 | 
			
		||||
	uint tile;
 | 
			
		||||
@@ -1159,6 +1143,12 @@ int32 CmdRemoveSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
	return _price.remove_signals;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Stub for the unified Signal builder/remover */
 | 
			
		||||
int32 CmdRemoveSignalTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
			
		||||
{
 | 
			
		||||
	return CmdSignalTrackHelper(x, y, flags, p1, SETBIT(p2, 1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef int32 DoConvertRailProc(uint tile, uint totype, bool exec);
 | 
			
		||||
 | 
			
		||||
static int32 DoConvertRail(uint tile, uint totype, bool exec)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										99
									
								
								rail_gui.c
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								rail_gui.c
									
									
									
									
									
								
							@@ -309,117 +309,45 @@ static void BuildRailClick_Landscaping(Window *w)
 | 
			
		||||
	ShowTerraformToolbar();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void DoRailroadTrack(int mode)
 | 
			
		||||
{
 | 
			
		||||
	DoCommandP(TILE_FROM_XY(_thd.selstart.x, _thd.selstart.y), PACK_POINT(_thd.selend.x, _thd.selend.y), (mode << 4) | _cur_railtype, NULL,
 | 
			
		||||
	DoCommandP(TILE_FROM_XY(_thd.selstart.x, _thd.selstart.y), TILE_FROM_XY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4), NULL,
 | 
			
		||||
		_remove_button_clicked ?
 | 
			
		||||
		CMD_REMOVE_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) :
 | 
			
		||||
		CMD_BUILD_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK)
 | 
			
		||||
		CMD_BUILD_RAILROAD_TRACK  | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK)
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// This function is more or less a hack because DoRailroadTrack() would otherwise screw up
 | 
			
		||||
static void SwapSelection(void)
 | 
			
		||||
{
 | 
			
		||||
	TileHighlightData *thd = &_thd;
 | 
			
		||||
	Point pt = thd->selstart;
 | 
			
		||||
	thd->selstart.x = thd->selend.x & ~0xF;
 | 
			
		||||
	thd->selstart.y = thd->selend.y & ~0xF;
 | 
			
		||||
	thd->selend = pt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void HandleAutodirPlacement(void)
 | 
			
		||||
{
 | 
			
		||||
	TileHighlightData *thd = &_thd;
 | 
			
		||||
	int bit;
 | 
			
		||||
	int dx = thd->selstart.x - (thd->selend.x&~0xF);
 | 
			
		||||
	int dy = thd->selstart.y - (thd->selend.y&~0xF);
 | 
			
		||||
	int trackstat = thd->drawstyle & 0xF; // 0..5
 | 
			
		||||
 | 
			
		||||
	if (thd->drawstyle & HT_RAIL) { // one tile case
 | 
			
		||||
		bit = thd->drawstyle & 0xF;
 | 
			
		||||
		GenericPlaceRail(TILE_FROM_XY(thd->selend.x, thd->selend.y), bit);
 | 
			
		||||
	} else if ( !(thd->drawstyle & 0xE) ) { // x/y dir
 | 
			
		||||
		if (dx == 0) { // Y dir
 | 
			
		||||
			DoRailroadTrack(1);
 | 
			
		||||
		} else {
 | 
			
		||||
			DoRailroadTrack(2);
 | 
			
		||||
		}
 | 
			
		||||
	} else if (myabs(dx)+myabs(dy) >= 32) { // long line (more than 2 tiles)
 | 
			
		||||
		if(thd->drawstyle == (HT_LINE | HT_DIR_HU))
 | 
			
		||||
			DoRailroadTrack(0);
 | 
			
		||||
		if(thd->drawstyle == (HT_LINE | HT_DIR_HL))
 | 
			
		||||
			DoRailroadTrack(3);
 | 
			
		||||
		if(thd->drawstyle == (HT_LINE | HT_DIR_VL))
 | 
			
		||||
			DoRailroadTrack(3);
 | 
			
		||||
		if(thd->drawstyle == (HT_LINE | HT_DIR_VR))
 | 
			
		||||
			DoRailroadTrack(0);
 | 
			
		||||
	} else { // 2x1 pieces line
 | 
			
		||||
		if(thd->drawstyle == (HT_LINE | HT_DIR_HU)) {
 | 
			
		||||
			DoRailroadTrack(0);
 | 
			
		||||
		} else if (thd->drawstyle == (HT_LINE | HT_DIR_HL)) {
 | 
			
		||||
			SwapSelection();
 | 
			
		||||
			DoRailroadTrack(0);
 | 
			
		||||
			SwapSelection();
 | 
			
		||||
		} else if (thd->drawstyle == (HT_LINE | HT_DIR_VL)) {
 | 
			
		||||
			if(dx == 0) {
 | 
			
		||||
				SwapSelection();
 | 
			
		||||
				DoRailroadTrack(0);
 | 
			
		||||
				SwapSelection();
 | 
			
		||||
			} else {
 | 
			
		||||
				DoRailroadTrack(3);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (thd->drawstyle == (HT_LINE | HT_DIR_VR)) {
 | 
			
		||||
			if(dx == 0) {
 | 
			
		||||
				DoRailroadTrack(0);
 | 
			
		||||
			} else {
 | 
			
		||||
				SwapSelection();
 | 
			
		||||
				DoRailroadTrack(3);
 | 
			
		||||
				SwapSelection();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		GenericPlaceRail(TILE_FROM_XY(thd->selend.x, thd->selend.y), trackstat);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DoRailroadTrack(trackstat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void HandleAutoSignalPlacement(void)
 | 
			
		||||
{
 | 
			
		||||
	TileHighlightData *thd = &_thd;
 | 
			
		||||
	int mode = 0;
 | 
			
		||||
	uint trackstat = 0;
 | 
			
		||||
 | 
			
		||||
	int dx = thd->selstart.x - (thd->selend.x&~0xF);
 | 
			
		||||
	int dy = thd->selstart.y - (thd->selend.y&~0xF);
 | 
			
		||||
	byte trackstat = thd->drawstyle & 0xF; // 0..5
 | 
			
		||||
 | 
			
		||||
	if (thd->drawstyle == HT_RECT) { // one tile case
 | 
			
		||||
		GenericPlaceSignals(TILE_FROM_XY(thd->selend.x, thd->selend.y));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(thd->drawstyle & 0xE)) { // X/Y direction
 | 
			
		||||
		mode = (dx == 0) ? VPM_FIX_X : VPM_FIX_Y;
 | 
			
		||||
		trackstat = 0xC0;
 | 
			
		||||
	} else if (myabs(dx) + myabs(dy) >= 32) { // long line (more than 2 tiles)
 | 
			
		||||
		mode = ((thd->drawstyle & 0xF) == HT_DIR_HU || (thd->drawstyle & 0xF) == HT_DIR_VR) ? 0 : 3;
 | 
			
		||||
 | 
			
		||||
		if (dx == dy || abs(dx - dy) == 16) // North<->South track |
 | 
			
		||||
			trackstat = (thd->drawstyle & 1) ? 0x20 : 0x10;
 | 
			
		||||
		else if (dx == -dy || abs(dx + dy) == 16) // East<->West track --
 | 
			
		||||
			trackstat = (thd->drawstyle & 1) ? 8 : 4;
 | 
			
		||||
 | 
			
		||||
	} else { // 2x1 pieces line
 | 
			
		||||
		GenericPlaceSignals(TILE_FROM_XY(thd->selstart.x, thd->selstart.y));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// _patches.drag_signals_density is given as a parameter such that each user in a network
 | 
			
		||||
	// game can specify his/her own signal density
 | 
			
		||||
	DoCommandP(TILE_FROM_XY(thd->selstart.x, thd->selstart.y), TILE_FROM_XY(thd->selend.x, thd->selend.y),
 | 
			
		||||
	(mode << 4) | (_remove_button_clicked | _ctrl_pressed) | (trackstat << 8) | (_patches.drag_signals_density << 24),
 | 
			
		||||
	(_ctrl_pressed ? 1 << 3 : 0) | (trackstat << 4) | (_patches.drag_signals_density << 24),
 | 
			
		||||
	CcPlaySound1E,
 | 
			
		||||
	(_remove_button_clicked ?	CMD_BUILD_MANY_SIGNALS | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) :
 | 
			
		||||
														CMD_BUILD_MANY_SIGNALS | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE) ) );
 | 
			
		||||
	(_remove_button_clicked ?	CMD_REMOVE_SIGNAL_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) :
 | 
			
		||||
	                          CMD_BUILD_SIGNAL_TRACK  | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE) ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static OnButtonClick * const _build_railroad_button_proc[] = {
 | 
			
		||||
@@ -527,9 +455,8 @@ static void BuildRailToolbWndProc(Window *w, WindowEvent *e)
 | 
			
		||||
				DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_LEVEL_LAND | CMD_AUTO);
 | 
			
		||||
			} else if (e->place.userdata == VPM_X_AND_Y_LIMITED) {
 | 
			
		||||
				HandleStationPlacement(start_tile, end_tile);
 | 
			
		||||
			} else {
 | 
			
		||||
				DoRailroadTrack(e->place.userdata);
 | 
			
		||||
			}
 | 
			
		||||
			} else
 | 
			
		||||
				DoRailroadTrack(e->place.userdata & 1);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user