diff --git a/bin/data/cmclient-2.grf b/bin/data/cmclient-2.grf index 4a74b72a42..6b2fec279f 100644 Binary files a/bin/data/cmclient-2.grf and b/bin/data/cmclient-2.grf differ diff --git a/grf/cmclient.nml b/grf/cmclient.nml index 02576f47e3..acdcc67e71 100644 --- a/grf/cmclient.nml +++ b/grf/cmclient.nml @@ -505,6 +505,14 @@ replace border_highlight(10029, "sprites/borderhighlight.png") { recolour_sprite { 0x00: 0x94; 0x01: 0x9b; 0x02: 0x9c; 0x03: 0x9d; 0x04: 0x9d; 0x05: 0x9e; 0x06: 0x9e; 0x07: 0xd6; 0x08: 0xd6; 0x09: 0x9f; 0x0a: 0x9f; 0x0b: 0xd5; 0x0c: 0xd5; 0x0d: 0xa0; 0x0e: 0xa0; 0x0f: 0x99; 0x10: 0x9d; 0x11: 0x9e; 0x12: 0x9e; 0x13: 0xd6; 0x14: 0x9f; 0x15: 0xcd; 0x16: 0xd5; 0x17: 0x98; 0x18: 0x9c; 0x19: 0x9d; 0x1a: 0x9d; 0x1b: 0x64; 0x1c: 0x9e; 0x1d: 0xd6; 0x1e: 0x9f; 0x1f: 0xd5; 0x20: 0x9d; 0x21: 0x9d; 0x22: 0x9e; 0x23: 0x9e; 0x24: 0xd6; 0x25: 0x9f; 0x26: 0xd5; 0x27: 0xa0; 0x28: 0x9c; 0x29: 0x9c; 0x2a: 0x9d; 0x2b: 0x13; 0x2c: 0x9e; 0x2d: 0xd6; 0x2e: 0x9f; 0x2f: 0x9f; 0x30: 0xd5; 0x31: 0xa0; 0x32: 0xd1; 0x33: 0x5f; 0x34: 0x67; 0x35: 0x9d; 0x36: 0x63; 0x37: 0x64; 0x38: 0x65; 0x39: 0x65; 0x3a: 0x9f; 0x3b: 0x9f; 0x3c: 0x9c; 0x3d: 0x63; 0x3e: 0x64; 0x3f: 0x64; 0x40: 0x65; 0x41: 0x5e; 0x42: 0xd1; 0x43: 0xd1; 0x44: 0x67; 0x45: 0xd4; 0x46: 0x9b; 0x47: 0x9c; 0x48: 0x9d; 0x49: 0x9d; 0x4a: 0x64; 0x4b: 0x9e; 0x4c: 0x65; 0x4d: 0x65; 0x4e: 0x9f; 0x4f: 0x9f; 0x50: 0x9c; 0x51: 0x9c; 0x52: 0x9d; 0x53: 0x9d; 0x54: 0x9d; 0x55: 0x64; 0x56: 0x64; 0x57: 0x65; 0x58: 0x9c; 0x59: 0x9d; 0x5a: 0x9d; 0x5b: 0x9e; 0x5c: 0x9e; 0x5d: 0xd6; 0x5e: 0x9f; 0x5f: 0x66; 0x60: 0x9c; 0x61: 0x9d; 0x62: 0x9d; 0x63: 0x9e; 0x64: 0xd6; 0x65: 0xd6; 0x66: 0xcd; 0x67: 0xd5; 0x68: 0x9c; 0x69: 0x9c; 0x6a: 0x9d; 0x6b: 0x9d; 0x6c: 0x9d; 0x6d: 0x64; 0x6e: 0x9e; 0x6f: 0xd6; 0x70: 0x9d; 0x71: 0x9d; 0x72: 0x64; 0x73: 0x9e; 0x74: 0x65; 0x75: 0x65; 0x76: 0x65; 0x77: 0x66; 0x78: 0x66; 0x79: 0x66; 0x7a: 0x9c; 0x7b: 0x9d; 0x7c: 0x64; 0x7d: 0x9e; 0x7e: 0xd6; 0x7f: 0x9f; 0x80: 0x9d; 0x81: 0x9d; 0x82: 0xcb; 0x83: 0x9e; 0x84: 0xd6; 0x85: 0xcd; 0x86: 0xd5; 0x87: 0x98; 0x88: 0xca; 0x89: 0xcb; 0x8a: 0xcc; 0x8b: 0xcc; 0x8c: 0x96; 0x8d: 0x97; 0x8e: 0x97; 0x8f: 0x98; 0x90: 0xca; 0x91: 0x94; 0x92: 0x95; 0x93: 0x95; 0x94: 0x95; 0x95: 0x96; 0x96: 0x96; 0x97: 0x97; 0x98: 0x97; 0x99: 0x98; 0x9a: 0xca; 0x9b: 0xcb; 0x9c: 0xcb; 0x9d: 0xcb; 0x9e: 0xcc; 0x9f: 0xcd; 0xa0: 0x98; 0xa1: 0x98; 0xa2: 0x13; 0xa3: 0x08; 0xa4: 0x08; 0xa5: 0x09; 0xa6: 0x66; 0xa7: 0xa0; 0xa8: 0xa0; 0xa9: 0xd4; 0xaa: 0xca; 0xab: 0xcb; 0xac: 0xcc; 0xad: 0xcc; 0xae: 0xcd; 0xaf: 0x98; 0xb0: 0x98; 0xb1: 0x98; 0xb2: 0x9c; 0xb3: 0x9c; 0xb4: 0x12; 0xb5: 0x06; 0xb6: 0x06; 0xb7: 0x07; 0xb8: 0x7e; 0xb9: 0x1d; 0xba: 0x5e; 0xbb: 0x5e; 0xbc: 0x5e; 0xbd: 0xd1; 0xbe: 0xd1; 0xbf: 0xd1; 0xc0: 0x5e; 0xc1: 0x5e; 0xc2: 0x5e; 0xc3: 0x5f; 0xc4: 0x66; 0xc5: 0x67; 0xc6: 0xca; 0xc7: 0xca; 0xc8: 0x95; 0xc9: 0x95; 0xca: 0x95; 0xcb: 0x96; 0xcc: 0x96; 0xcd: 0x97; 0xce: 0x9e; 0xcf: 0xd6; 0xd0: 0x65; 0xd1: 0x9f; 0xd2: 0x98; 0xd3: 0x98; 0xd4: 0x98; 0xd5: 0xcd; 0xd6: 0xcc; 0xd7: 0x8d; 0xd8: 0x8d; 0xd9: 0x8d; 0xda: 0x8d; 0xdb: 0x8d; 0xdc: 0x8d; 0xdd: 0x8d; 0xde: 0x8d; 0xdf: 0x8d; 0xe0: 0x8d; 0xe1: 0x8d; 0xe2: 0x8d; 0xe3: 0x9c; 0xe4: 0x9d; 0xe5: 0x9e; 0xe6: 0x65; 0xe7: 0x9f; 0xe8: 0x1d; 0xe9: 0x1d; 0xea: 0x5e; 0xeb: 0x5e; 0xec: 0x5e; 0xed: 0xd1; 0xee: 0xd1; 0xef: 0x9c; 0xf0: 0x7e; 0xf1: 0x9c; 0xf2: 0x9d; 0xf3: 0x63; 0xf4: 0xd1; 0xf5: 0xcb; 0xf6: 0xcb; 0xf7: 0xcb; 0xf8: 0xcb; 0xf9: 0xcb; 0xfa: 0xcc; 0xfb: 0xcc; 0xfc: 0x98; 0xfd: 0xcc; 0xfe: 0xcb; 0xff: 0x99; } + // cyan white tint + recolour_sprite { + 0x00: 0x95; 0x01: 0x9d; 0x02: 0x9d; 0x03: 0x64; 0x04: 0x9e; 0x05: 0x9e; 0x06: 0xd6; 0x07: 0x9f; 0x08: 0x9f; 0x09: 0x66; 0x0a: 0xa0; 0x0b: 0xa0; 0x0c: 0xd4; 0x0d: 0xd4; 0x0e: 0xd3; 0x0f: 0xa1; 0x10: 0x9e; 0x11: 0x9e; 0x12: 0xd6; 0x13: 0x9f; 0x14: 0x9f; 0x15: 0xd5; 0x16: 0xa0; 0x17: 0xd4; 0x18: 0x64; 0x19: 0x64; 0x1a: 0x64; 0x1b: 0x65; 0x1c: 0x65; 0x1d: 0x66; 0x1e: 0x66; 0x1f: 0x67; 0x20: 0x64; 0x21: 0x64; 0x22: 0x65; 0x23: 0x65; 0x24: 0x66; 0x25: 0x66; 0x26: 0x67; 0x27: 0x67; 0x28: 0x12; 0x29: 0x06; 0x2a: 0x07; 0x2b: 0x08; 0x2c: 0x09; 0x2d: 0x15; 0x2e: 0x0a; 0x2f: 0x0b; 0x30: 0x0c; 0x31: 0x17; 0x32: 0x5f; 0x33: 0x5f; 0x34: 0x67; 0x35: 0x64; 0x36: 0x64; 0x37: 0x65; 0x38: 0x65; 0x39: 0x66; 0x3a: 0x66; 0x3b: 0x67; 0x3c: 0x06; 0x3d: 0x64; 0x3e: 0x5d; 0x3f: 0x1d; 0x40: 0x5e; 0x41: 0x5f; 0x42: 0x5f; 0x43: 0x5f; 0x44: 0x67; 0x45: 0xd3; 0x46: 0x63; 0x47: 0x06; 0x48: 0x07; 0x49: 0x07; 0x4a: 0x08; 0x4b: 0x08; 0x4c: 0x09; 0x4d: 0x0a; 0x4e: 0x0a; 0x4f: 0x0b; 0x50: 0x63; 0x51: 0x63; 0x52: 0x64; 0x53: 0x64; 0x54: 0x64; 0x55: 0x65; 0x56: 0x65; 0x57: 0x65; 0x58: 0x64; 0x59: 0x64; 0x5a: 0x64; 0x5b: 0x65; 0x5c: 0x65; 0x5d: 0x66; 0x5e: 0x66; 0x5f: 0x66; 0x60: 0x9d; 0x61: 0x9e; 0x62: 0x9e; 0x63: 0xd6; 0x64: 0x9f; 0x65: 0x9f; 0x66: 0xa0; 0x67: 0xd4; 0x68: 0x63; 0x69: 0x63; 0x6a: 0x64; 0x6b: 0x64; 0x6c: 0x64; 0x6d: 0x65; 0x6e: 0x65; 0x6f: 0x66; 0x70: 0x64; 0x71: 0x64; 0x72: 0x08; 0x73: 0x65; 0x74: 0x09; 0x75: 0x0a; 0x76: 0x0a; 0x77: 0x0b; 0x78: 0x0b; 0x79: 0x67; 0x7a: 0x06; 0x7b: 0x07; 0x7c: 0x08; 0x7d: 0x14; 0x7e: 0x15; 0x7f: 0x86; 0x80: 0x9e; 0x81: 0x9e; 0x82: 0x9e; 0x83: 0xd6; 0x84: 0x9f; 0x85: 0xd5; 0x86: 0xa0; 0x87: 0xd4; 0x88: 0xcb; 0x89: 0xd6; 0x8a: 0xcc; 0x8b: 0xcd; 0x8c: 0xcd; 0x8d: 0x98; 0x8e: 0x98; 0x8f: 0xd4; 0x90: 0xcb; 0x91: 0xcb; 0x92: 0xcb; 0x93: 0x96; 0x94: 0x96; 0x95: 0x97; 0x96: 0x97; 0x97: 0x98; 0x98: 0x98; 0x99: 0x99; 0x9a: 0x9e; 0x9b: 0x9e; 0x9c: 0xd6; 0x9d: 0xd6; 0x9e: 0x9f; 0x9f: 0xd5; 0xa0: 0xa0; 0xa1: 0x99; 0xa2: 0x08; 0xa3: 0x7f; 0xa4: 0x7f; 0xa5: 0x3b; 0xa6: 0x1f; 0xa7: 0x0c; 0xa8: 0x0d; 0xa9: 0xa1; 0xaa: 0x9e; 0xab: 0xd6; 0xac: 0x9f; 0xad: 0xd5; 0xae: 0xa0; 0xaf: 0xd4; 0xb0: 0x99; 0xb1: 0x99; 0xb2: 0x12; 0xb3: 0x06; 0xb4: 0x07; 0xb5: 0x7e; 0xb6: 0x7e; 0xb7: 0x4d; 0xb8: 0x2e; 0xb9: 0x77; 0xba: 0x77; 0xbb: 0x25; 0xbc: 0x5f; 0xbd: 0x5f; 0xbe: 0x5f; 0xbf: 0x34; 0xc0: 0x5e; 0xc1: 0x5f; 0xc2: 0x5f; 0xc3: 0x5f; 0xc4: 0x1f; 0xc5: 0x67; 0xc6: 0x9d; 0xc7: 0xcb; 0xc8: 0xcb; 0xc9: 0xcb; 0xca: 0xcc; 0xcb: 0xcd; 0xcc: 0xcd; 0xcd: 0x98; 0xce: 0x65; 0xcf: 0x65; 0xd0: 0x66; 0xd1: 0x66; 0xd2: 0xd3; 0xd3: 0x99; 0xd4: 0xd4; 0xd5: 0x98; 0xd6: 0x9f; 0xd7: 0x8e; 0xd8: 0x8e; 0xd9: 0x8e; 0xda: 0x8e; 0xdb: 0x8e; 0xdc: 0x8e; 0xdd: 0x8e; 0xde: 0x8e; 0xdf: 0x8e; 0xe0: 0x8e; 0xe1: 0x8e; 0xe2: 0x8e; 0xe3: 0x06; 0xe4: 0x07; 0xe5: 0x08; 0xe6: 0x09; 0xe7: 0x0b; 0xe8: 0x76; 0xe9: 0x77; 0xea: 0x77; 0xeb: 0x25; 0xec: 0x5f; 0xed: 0x5f; 0xee: 0x5f; 0xef: 0x06; 0xf0: 0x2e; 0xf1: 0x64; 0xf2: 0x64; 0xf3: 0x64; 0xf4: 0x34; 0xf5: 0x9e; 0xf6: 0x9e; 0xf7: 0xd6; 0xf8: 0xd6; 0xf9: 0xd6; 0xfa: 0xd6; 0xfb: 0x9f; 0xfc: 0xd3; 0xfd: 0x9f; 0xfe: 0xd6; 0xff: 0xa1; + } + // blue tint + recolour_sprite { + 0x00: 0x93; 0x01: 0x90; 0x02: 0x88; 0x03: 0x88; 0x04: 0x89; 0x05: 0x89; 0x06: 0x89; 0x07: 0x8a; 0x08: 0x8a; 0x09: 0x8b; 0x0a: 0x8b; 0x0b: 0x8c; 0x0c: 0x8c; 0x0d: 0x8d; 0x0e: 0x8e; 0x0f: 0x8e; 0x10: 0xc8; 0x11: 0x89; 0x12: 0x89; 0x13: 0x8a; 0x14: 0x8b; 0x15: 0x8b; 0x16: 0x8c; 0x17: 0x8d; 0x18: 0x88; 0x19: 0x88; 0x1a: 0x88; 0x1b: 0x82; 0x1c: 0x83; 0x1d: 0x8a; 0x1e: 0x8b; 0x1f: 0xad; 0x20: 0x88; 0x21: 0x88; 0x22: 0x89; 0x23: 0x89; 0x24: 0x8a; 0x25: 0xac; 0x26: 0xad; 0x27: 0xae; 0x28: 0x88; 0x29: 0x88; 0x2a: 0xaa; 0x2b: 0xaa; 0x2c: 0xab; 0x2d: 0xac; 0x2e: 0xac; 0x2f: 0xad; 0x30: 0xad; 0x31: 0xad; 0x32: 0x24; 0x33: 0x09; 0x34: 0x15; 0x35: 0x88; 0x36: 0xaa; 0x37: 0x82; 0x38: 0x83; 0x39: 0x84; 0x3a: 0xac; 0x3b: 0xad; 0x3c: 0x88; 0x3d: 0xaa; 0x3e: 0xaa; 0x3f: 0x83; 0x40: 0x83; 0x41: 0x07; 0x42: 0x07; 0x43: 0x24; 0x44: 0x15; 0x45: 0xae; 0x46: 0xc6; 0x47: 0x88; 0x48: 0x88; 0x49: 0xaa; 0x4a: 0xaa; 0x4b: 0xab; 0x4c: 0xab; 0x4d: 0xac; 0x4e: 0xac; 0x4f: 0xad; 0x50: 0xc7; 0x51: 0xc7; 0x52: 0xc7; 0x53: 0x9a; 0x54: 0x9b; 0x55: 0x9c; 0x56: 0x83; 0x57: 0x12; 0x58: 0xc7; 0x59: 0xc8; 0x5a: 0xc8; 0x5b: 0xc9; 0x5c: 0x89; 0x5d: 0x8a; 0x5e: 0x84; 0x5f: 0x85; 0x60: 0xc7; 0x61: 0xc8; 0x62: 0xc9; 0x63: 0xc9; 0x64: 0xca; 0x65: 0xcb; 0x66: 0xcb; 0x67: 0xcd; 0x68: 0xc6; 0x69: 0x88; 0x6a: 0x88; 0x6b: 0x88; 0x6c: 0xaa; 0x6d: 0x89; 0x6e: 0xab; 0x6f: 0xac; 0x70: 0x88; 0x71: 0xaa; 0x72: 0x89; 0x73: 0xab; 0x74: 0xab; 0x75: 0xac; 0x76: 0xac; 0x77: 0xac; 0x78: 0xad; 0x79: 0xad; 0x7a: 0x88; 0x7b: 0xaa; 0x7c: 0xaa; 0x7d: 0xab; 0x7e: 0x8a; 0x7f: 0x8b; 0x80: 0x91; 0x81: 0x91; 0x82: 0x89; 0x83: 0x89; 0x84: 0x8a; 0x85: 0x8b; 0x86: 0x8c; 0x87: 0x8d; 0x88: 0x92; 0x89: 0x92; 0x8a: 0x8a; 0x8b: 0x8a; 0x8c: 0x8b; 0x8d: 0x8c; 0x8e: 0x8c; 0x8f: 0x8d; 0x90: 0x92; 0x91: 0x92; 0x92: 0x93; 0x93: 0x93; 0x94: 0x94; 0x95: 0x94; 0x96: 0x95; 0x97: 0x95; 0x98: 0x96; 0x99: 0x8d; 0x9a: 0x92; 0x9b: 0x92; 0x9c: 0x92; 0x9d: 0x93; 0x9e: 0xca; 0x9f: 0xcb; 0xa0: 0xcc; 0xa1: 0x8e; 0xa2: 0xab; 0xa3: 0xab; 0xa4: 0xab; 0xa5: 0xac; 0xa6: 0xad; 0xa7: 0xad; 0xa8: 0xae; 0xa9: 0x8e; 0xaa: 0x89; 0xab: 0x89; 0xac: 0x8a; 0xad: 0x8b; 0xae: 0x8c; 0xaf: 0x8d; 0xb0: 0x8d; 0xb1: 0x8d; 0xb2: 0x88; 0xb3: 0x88; 0xb4: 0xaa; 0xb5: 0xaa; 0xb6: 0xaa; 0xb7: 0x2b; 0xb8: 0x2b; 0xb9: 0x2c; 0xba: 0x2c; 0xbb: 0x7e; 0xbc: 0x7e; 0xbd: 0x7e; 0xbe: 0x24; 0xbf: 0x1d; 0xc0: 0x06; 0xc1: 0x7e; 0xc2: 0x7e; 0xc3: 0x08; 0xc4: 0x85; 0xc5: 0xad; 0xc6: 0x91; 0xc7: 0x92; 0xc8: 0x92; 0xc9: 0x92; 0xca: 0x93; 0xcb: 0x94; 0xcc: 0x95; 0xcd: 0x96; 0xce: 0x9d; 0xcf: 0x9d; 0xd0: 0x9e; 0xd1: 0x9e; 0xd2: 0x8e; 0xd3: 0x8e; 0xd4: 0x97; 0xd5: 0x96; 0xd6: 0xcb; 0xd7: 0x8c; 0xd8: 0x8c; 0xd9: 0x8c; 0xda: 0x8c; 0xdb: 0x8c; 0xdc: 0x8c; 0xdd: 0x8c; 0xde: 0x8c; 0xdf: 0x8c; 0xe0: 0x8c; 0xe1: 0x8c; 0xe2: 0x8c; 0xe3: 0x88; 0xe4: 0xaa; 0xe5: 0xab; 0xe6: 0xac; 0xe7: 0xac; 0xe8: 0x2c; 0xe9: 0x2c; 0xea: 0x2c; 0xeb: 0x7e; 0xec: 0x7e; 0xed: 0x7e; 0xee: 0x24; 0xef: 0x88; 0xf0: 0x2b; 0xf1: 0x88; 0xf2: 0x88; 0xf3: 0x81; 0xf4: 0x1d; 0xf5: 0x92; 0xf6: 0x92; 0xf7: 0x92; 0xf8: 0x92; 0xf9: 0x92; 0xfa: 0xca; 0xfb: 0xcb; 0xfc: 0x8e; 0xfd: 0xca; 0xfe: 0xca; 0xff: 0x8e; + } } diff --git a/grf/recolourgen.py b/grf/recolourgen.py index 9e5f95134a..0fcc5fe9ea 100644 --- a/grf/recolourgen.py +++ b/grf/recolourgen.py @@ -70,3 +70,5 @@ gen_recolor(spectra.rgb(1.0, 1.0, 0.5), 0.4, "yellow white tint") gen_recolor(spectra.rgb(1.0, 1.0, 1.0), 0.4, "white tint") gen_recolor(spectra.rgb(0, 1.0, 0), 0.4, "green tint") gen_recolor(spectra.rgb(0, 1.0, 1.0), 0.4, "cyan tint") +gen_recolor(spectra.rgb(0.5, 1.0, 1.0), 0.4, "cyan white tint") +gen_recolor(spectra.rgb(0, 0, 1.0), 0.4, "blue tint") diff --git a/src/citymania/highlight.cpp b/src/citymania/highlight.cpp index e61cc7d1cd..45eccd56ec 100644 --- a/src/citymania/highlight.cpp +++ b/src/citymania/highlight.cpp @@ -5,6 +5,7 @@ #include "../core/math_func.hpp" #include "../house.h" #include "../industry.h" +#include "../landscape.h" #include "../town.h" #include "../tilearea_type.h" #include "../tilehighlight_type.h" @@ -34,7 +35,9 @@ struct TileZoning { static TileZoning *_mz = nullptr; static IndustryType _industry_forbidden_tiles = INVALID_INDUSTRYTYPE; -BuildingPossibility _station_possibility = BuildingPossibility::OK; +StationBuildingStatus _station_building_status = StationBuildingStatus::NEW; +const Station *_station_to_join = nullptr; +TileArea _station_to_join_area; // struct { // int w; // int h; @@ -119,25 +122,94 @@ SpriteID GetIndustryZoningPalette(TileIndex tile) { return PAL_NONE; } +SpriteID GetTintBySelectionColour(SpriteID colour, bool deep=false) { + switch(colour) { + case SPR_PALETTE_ZONING_RED: return (deep ? PALETTE_TINT_RED_DEEP : PALETTE_TINT_RED); + case SPR_PALETTE_ZONING_ORANGE: return (deep ? PALETTE_TINT_ORANGE_DEEP : PALETTE_TINT_ORANGE); + case SPR_PALETTE_ZONING_GREEN: return (deep ? PALETTE_TINT_GREEN_DEEP : PALETTE_TINT_GREEN); + case SPR_PALETTE_ZONING_LIGHT_BLUE: return (deep ? PALETTE_TINT_CYAN_DEEP : PALETTE_TINT_CYAN); + case SPR_PALETTE_ZONING_YELLOW: return PALETTE_TINT_YELLOW; + // case SPR_PALETTE_ZONING__: return PALETTE_TINT_YELLOW_WHITE; + case SPR_PALETTE_ZONING_WHITE: return PALETTE_TINT_WHITE; + default: return PAL_NONE; + } +} + +static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th) { + bool draw_coverage = false; + bool draw_selection = false; + if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0) { + // we have station selected + draw_selection = true; + draw_coverage = _settings_client.gui.station_show_coverage; + } + + if (draw_selection) { + auto b = CalcTileBorders(ti->tile, [](TileIndex t) { + auto x = TileX(t) * TILE_SIZE, y = TileY(t) * TILE_SIZE; + return IsInsideSelectedRectangle(x, y); + }); + if (b.first != ZoningBorder::NONE) { + const SpriteID pal[] = {SPR_PALETTE_ZONING_RED, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_LIGHT_BLUE, SPR_PALETTE_ZONING_GREEN}; + auto color = pal[(int)_station_building_status]; + th.add_border(b.first, color); + th.ground_pal = GetTintBySelectionColour(color); + return; + } + } + + auto highlight_station = _station_to_join ? _station_to_join : _viewport_highlight_station; + auto coverage_getter = [draw_coverage, highlight_station](TileIndex t) { + auto x = TileX(t) * TILE_SIZE, y = TileY(t) * TILE_SIZE; + if (highlight_station && IsTileType(t, MP_STATION) && GetStationIndex(t) == highlight_station->index) return 2; + if (draw_coverage && highlight_station && highlight_station->TileIsInCatchment(t)) return 1; + if (draw_coverage && IsInsideBS(x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) && + IsInsideBS(y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) return 1; + return 0; + }; + auto b = CalcTileBorders(ti->tile, coverage_getter); + if (b.second) { + const SpriteID pal[] = {PAL_NONE, SPR_PALETTE_ZONING_WHITE, SPR_PALETTE_ZONING_LIGHT_BLUE}; + th.add_border(b.first, pal[b.second]); + const SpriteID pal2[] = {PAL_NONE, PALETTE_TINT_WHITE, PALETTE_TINT_BLUE}; + th.ground_pal = th.structure_pal = pal2[b.second]; + } + + if (_station_to_join) { + auto b = CalcTileBorders(ti->tile, [](TileIndex t) { + + return _station_to_join_area.Contains(t) ? 1 : 0; + }); + th.add_border(b.first, SPR_PALETTE_ZONING_LIGHT_BLUE); + if (b.second) { + switch (th.ground_pal) { + case PALETTE_TINT_WHITE: th.ground_pal = th.structure_pal = PALETTE_TINT_CYAN_WHITE; break; + case PALETTE_TINT_BLUE: break; + default: th.ground_pal = th.structure_pal = PALETTE_TINT_CYAN; break; + } + } + } +} + TileHighlight GetTileHighlight(const TileInfo *ti) { TileHighlight th; if (ti->tile == INVALID_TILE) return th; if (_zoning.outer == CHECKTOWNZONES) { auto p = GetTownZoneBorder(ti->tile); - th.border = p.first; - auto pal = PAL_NONE; + auto color = PAL_NONE; switch (p.second) { default: break; // Tz0 - case 1: th.border_color = SPR_PALETTE_ZONING_WHITE; pal = PALETTE_TINT_WHITE; break; // Tz0 - case 2: th.border_color = SPR_PALETTE_ZONING_YELLOW; pal = PALETTE_TINT_YELLOW; break; // Tz1 - case 3: th.border_color = SPR_PALETTE_ZONING_ORANGE; pal = PALETTE_TINT_ORANGE; break; // Tz2 - case 4: th.border_color = SPR_PALETTE_ZONING_ORANGE; pal = PALETTE_TINT_ORANGE; break; // Tz3 - case 5: th.border_color = SPR_PALETTE_ZONING_RED; pal = PALETTE_TINT_RED; break; // Tz4 - center + case 1: color = SPR_PALETTE_ZONING_WHITE; break; // Tz0 + case 2: color = SPR_PALETTE_ZONING_YELLOW; break; // Tz1 + case 3: color = SPR_PALETTE_ZONING_ORANGE; break; // Tz2 + case 4: color = SPR_PALETTE_ZONING_ORANGE; break; // Tz3 + case 5: color = SPR_PALETTE_ZONING_RED; break; // Tz4 - center }; - th.ground_pal = th.structure_pal = pal; + th.add_border(p.first, color); + th.ground_pal = th.structure_pal = GetTintBySelectionColour(color); } else if (_zoning.outer == CHECKSTACATCH) { - th.border = citymania::GetAnyStationCatchmentBorder(ti->tile); - th.border_color = SPR_PALETTE_ZONING_LIGHT_BLUE; + th.add_border(citymania::GetAnyStationCatchmentBorder(ti->tile), + SPR_PALETTE_ZONING_LIGHT_BLUE); } else if (_zoning.outer == CHECKTOWNGROWTHTILES) { auto tgt = max(_towns_growth_tiles[ti->tile], _towns_growth_tiles_last_month[ti->tile]); // if (tgt == TGTS_NEW_HOUSE) th.sprite = SPR_IMG_HOUSE_NEW; @@ -145,30 +217,27 @@ TileHighlight GetTileHighlight(const TileInfo *ti) { case TGTS_CB_HOUSE_REMOVED_NOGROW: case TGTS_RH_REMOVED: th.selection = SPR_PALETTE_ZONING_LIGHT_BLUE; - th.ground_pal = PALETTE_TINT_CYAN; break; case TGTS_RH_REBUILT: th.selection = SPR_PALETTE_ZONING_WHITE; - th.ground_pal = th.structure_pal = PALETTE_TINT_WHITE; + th.structure_pal = PALETTE_TINT_WHITE; break; case TGTS_NEW_HOUSE: th.selection = SPR_PALETTE_ZONING_GREEN; - th.ground_pal = th.structure_pal = PALETTE_TINT_GREEN; + th.structure_pal = PALETTE_TINT_GREEN; break; case TGTS_CYCLE_SKIPPED: th.selection = SPR_PALETTE_ZONING_ORANGE; - th.ground_pal = PALETTE_TINT_ORANGE; break; case TGTS_HOUSE_SKIPPED: th.selection = SPR_PALETTE_ZONING_YELLOW; - th.ground_pal = PALETTE_TINT_YELLOW; break; case TGTS_CB_HOUSE_REMOVED: th.selection = SPR_PALETTE_ZONING_RED; - th.ground_pal = PALETTE_TINT_RED; break; default: th.selection = PAL_NONE; } + if (th.selection) th.ground_pal = GetTintBySelectionColour(th.selection); } else if (_zoning.outer == CHECKBULUNSER) { if (IsTileType (ti->tile, MP_HOUSE)) { StationFinder stations(TileArea(ti->tile, 1, 1)); @@ -183,21 +252,15 @@ TileHighlight GetTileHighlight(const TileInfo *ti) { } else if (_zoning.outer == CHECKTOWNADZONES) { auto getter = [](TileIndex t) { return _mz[t].advertisement_zone; }; auto b = CalcTileBorders(ti->tile, getter); - if (b.first != ZoningBorder::NONE) { - th.border = b.first; - const SpriteID pal[] = {PAL_NONE, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_ORANGE, SPR_PALETTE_ZONING_RED}; - th.border_color = pal[b.second]; - } + const SpriteID pal[] = {PAL_NONE, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_ORANGE, SPR_PALETTE_ZONING_RED}; + th.add_border(b.first, pal[b.second]); auto check_tile = ti->tile; if (IsTileType (ti->tile, MP_STATION)) { auto station = Station::GetByTile(ti->tile); if (station) check_tile = station->xy; } auto z = getter(check_tile); - if (z) { - const SpriteID pal[] = {PAL_NONE, PALETTE_TINT_YELLOW, PALETTE_TINT_ORANGE, PALETTE_TINT_RED}; - th.ground_pal = th.structure_pal = pal[z]; - } + if (z) th.ground_pal = th.structure_pal = GetTintBySelectionColour(pal[z]); } else if (_zoning.outer == CHECKACTIVESTATIONS) { auto getter = [](TileIndex t) { if (!IsTileType (t, MP_STATION)) return 0; @@ -208,71 +271,28 @@ TileHighlight GetTileHighlight(const TileInfo *ti) { return 2; }; auto b = CalcTileBorders(ti->tile, getter); - if (b.first != ZoningBorder::NONE) { - th.border = b.first; - const SpriteID pal[] = {PAL_NONE, SPR_PALETTE_ZONING_GREEN, SPR_PALETTE_ZONING_RED}; - th.border_color = pal[b.second]; - } + const SpriteID pal[] = {PAL_NONE, SPR_PALETTE_ZONING_GREEN, SPR_PALETTE_ZONING_RED}; + th.add_border(b.first, pal[b.second]); auto z = getter(ti->tile); - if (z) { - const SpriteID pal[] = {PAL_NONE, PALETTE_TINT_GREEN_DEEP, PALETTE_TINT_RED_DEEP}; - th.ground_pal = th.structure_pal = pal[z]; - } + if (z) th.ground_pal = th.structure_pal = GetTintBySelectionColour(pal[z]); } if (_settings_client.gui.show_industry_forbidden_tiles && _industry_forbidden_tiles != INVALID_INDUSTRYTYPE) { auto b = CalcTileBorders(ti->tile, [](TileIndex t) { return !CanBuildIndustryOnTileCached(_industry_forbidden_tiles, t); }); - if(b.first != ZoningBorder::NONE) { - th.border = b.first; - th.border_color = SPR_PALETTE_ZONING_RED; - } + th.add_border(b.first, SPR_PALETTE_ZONING_RED); if (!CanBuildIndustryOnTileCached(_industry_forbidden_tiles, ti->tile)) th.ground_pal = th.structure_pal = PALETTE_TINT_RED; } - bool draw_coverage = false; - bool draw_selection = false; - if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0) { - // we have station selected - draw_selection = true; - draw_coverage = _settings_client.gui.station_show_coverage; - } - auto getter = [draw_selection, draw_coverage](TileIndex t) { - auto x = TileX(t) * TILE_SIZE, y = TileY(t) * TILE_SIZE; - if (draw_selection && IsInsideSelectedRectangle(x, y)) return 3; - if (_viewport_highlight_station && IsTileType(t, MP_STATION) && GetStationIndex(t) == _viewport_highlight_station->index) return 2; - if (_viewport_highlight_station && _viewport_highlight_station->TileIsInCatchment(t)) return 1; - if (draw_coverage && IsInsideBS(x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) && - IsInsideBS(y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) return 1; - return 0; - }; - auto b = CalcTileBorders(ti->tile, getter); - if(b.first != ZoningBorder::NONE) { - th.border = b.first; - if (b.second == 3) { - const SpriteID pal[] = {SPR_PALETTE_ZONING_RED, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_GREEN}; - th.border_color = pal[(int)_station_possibility]; - } else { - const SpriteID pal[] = {PAL_NONE, SPR_PALETTE_ZONING_WHITE, SPR_PALETTE_ZONING_LIGHT_BLUE}; - th.border_color = pal[b.second]; - } - } - auto z = getter(ti->tile); - if (z == 3) { - const SpriteID pal[] = {PALETTE_TINT_RED, PALETTE_TINT_YELLOW, PALETTE_TINT_GREEN}; - th.ground_pal = th.structure_pal = pal[(int)_station_possibility]; - } else if (z) { - const SpriteID pal[] = {PAL_NONE, PALETTE_TINT_WHITE, PALETTE_TINT_CYAN_DEEP, PALETTE_TINT_GREEN_DEEP}; - th.ground_pal = th.structure_pal = pal[z]; - } + SetStationSelectionHighlight(ti, th); return th; } void DrawTileSelection(const TileInfo *ti, const TileHighlight &th) { - if (th.border != ZoningBorder::NONE) - DrawBorderSprites(ti, th.border, th.border_color); + for (uint i = 0; i < th.border_count; i++) + DrawBorderSprites(ti, th.border[i], th.border_color[i]); if (th.sprite) { DrawSelectionSprite(th.sprite, PAL_NONE, ti, 0, FOUNDATION_PART_NORMAL); } @@ -408,9 +428,65 @@ void SetIndustryForbiddenTilesHighlight(IndustryType type) { // _station_select.catchment = catchment; // } -void SetStationBiildingPossibility(BuildingPossibility possibility) { - _station_possibility = possibility; +void SetStationBiildingStatus(SetStationBiildingStatus status) { + _station_building_status = status; }; +static const int MAX_TILE_EXTENT_LEFT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner. +static const int MAX_TILE_EXTENT_RIGHT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner. +static const int MAX_TILE_EXTENT_TOP = ZOOM_LVL_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges). +static const int MAX_TILE_EXTENT_BOTTOM = ZOOM_LVL_BASE * (TILE_PIXELS + 2 * TILE_HEIGHT); ///< Maximum bottom extent of tile relative to north corner (worst case: #SLOPE_STEEP_N). + +void MarkTileAreaDirty(const TileArea &ta) { + if (ta.tile == INVALID_TILE) return; + auto x = TileX(ta.tile); + auto y = TileY(ta.tile); + Point p1 = RemapCoords(x * TILE_SIZE, y * TILE_SIZE, TileHeight(ta.tile) * TILE_HEIGHT); + Point p2 = RemapCoords((x + ta.w) * TILE_SIZE, (y + ta.h) * TILE_SIZE, TileHeight(TileXY(x + ta.w - 1, y + ta.h - 1)) * TILE_HEIGHT); + Point p3 = RemapCoords((x + ta.w) * TILE_SIZE, y * TILE_SIZE, TileHeight(TileXY(x + ta.w - 1, y)) * TILE_HEIGHT); + Point p4 = RemapCoords(x * TILE_SIZE, (y + ta.h) * TILE_SIZE, TileHeight(TileXY(x, y + ta.h - 1)) * TILE_HEIGHT); + MarkAllViewportsDirty( + p3.x - MAX_TILE_EXTENT_LEFT, + p4.x - MAX_TILE_EXTENT_TOP, + p1.y + MAX_TILE_EXTENT_RIGHT, + p2.y + MAX_TILE_EXTENT_BOTTOM); + // TILE_AREA_LOOP(tile, ta) { + // MarkTileDirtyByTile(tile); + // } +} + +static void UpdateStationToJoinArea() { + auto &r = station->rect; + auto d = (int)_settings_game.station.station_spread - 1; + ta = TileArea( + TileXY(max(r.right - d, 0), + max(r.bottom - d, 0)), + TileXY(min(r.left + d, MapSizeX() - 1), + min(r.top + d, MapSizeY() - 1)) + ); + if (_station_to_join_area == ta) return; + _station_to_join_area = ta; + MarkTileAreaDirty(_station_to_join_area); +} + +void MarkCoverageHighlightDirty() { + MarkCatchmentTilesDirty(); +} + +void SetStationToJoin(const Station *station) { + if (_station_to_join == station) { + _station_to_join = nullptr; + MarkTileAreaDirty(_station_to_join_area); + _station_to_join_area.Clear(); + } else { + _station_to_join = station; + UpdateStationToJoinArea(); + } +} + +const Station *GetStationToJoin() { + return _station_to_join; +} + } // namespace citymania diff --git a/src/citymania/highlight.hpp b/src/citymania/highlight.hpp index 80b87702ec..6b49d3221b 100644 --- a/src/citymania/highlight.hpp +++ b/src/citymania/highlight.hpp @@ -4,6 +4,7 @@ #include "../core/enum_type.hpp" #include "../gfx_type.h" #include "../industry_type.h" +#include "../station_type.h" #include "../tile_cmd.h" #include "../tile_type.h" #include "../town_type.h" @@ -26,10 +27,11 @@ enum ZoningBorder: uint8 { FULL = TOP_LEFT | TOP_RIGHT | BOTTOM_LEFT | BOTTOM_RIGHT, }; -enum class BuildingPossibility { +enum class StationBuildingStatus { IMPOSSIBLE = 0, QUERY = 1, - OK = 2, + JOIN = 2, + NEW = 3, }; class TileHighlight { @@ -38,8 +40,20 @@ public: SpriteID structure_pal = PAL_NONE; SpriteID sprite = 0; SpriteID selection = PAL_NONE; - ZoningBorder border = ZoningBorder::NONE; - SpriteID border_color; + ZoningBorder border[4] = {}; + SpriteID border_color[4] = {}; + uint border_count = 0; + + void add_border(ZoningBorder border, SpriteID color) { + if (border == ZoningBorder::NONE) return; + this->border[this->border_count] = border; + this->border_color[this->border_count] = color; + this->border_count++; + } + + void clear_borders() { + this->border_count = 0; + } }; DECLARE_ENUM_AS_BIT_SET(ZoningBorder); @@ -52,7 +66,7 @@ DECLARE_ENUM_AS_BIT_SET(ZoningBorder); // }; -void SetStationBiildingPossibility(BuildingPossibility possibility); +void SetStationBiildingStatus(StationBuildingStatus status); TileHighlight GetTileHighlight(const TileInfo *ti); void DrawTileSelection(const TileInfo *ti, const TileHighlight &th); @@ -72,6 +86,10 @@ SpriteID GetTownTileZoningPalette(TileIndex tile); SpriteID GetIndustryTileZoningPalette(TileIndex tile, Industry *ind); void SetIndustryForbiddenTilesHighlight(IndustryType type); +void SetStationToJoin(const Station *station); +const Station *GetStationToJoin(); +void MarkCoverageHighlightDirty(); + } // namespace citymania #endif diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index de7130cd0f..c0576cf5fb 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -39,6 +39,8 @@ #include "safeguards.h" +extern const Station *_viewport_highlight_station; // CM + void GuiShowTooltipsExtra(Window *parent, uint param, TooltipCloseCondition close_tooltip); /** Method to open the OSK. */ diff --git a/src/rev.cpp b/src/rev.cpp index 7d6b2ec00f..2a7ce919f6 100644 --- a/src/rev.cpp +++ b/src/rev.cpp @@ -83,4 +83,4 @@ const byte _openttd_revision_tagged = 1; const uint32 _openttd_newgrf_version = 1 << 28 | 10 << 24 | 0 << 20 | 0 << 19 | 28004; -const char _citymania_version[] = "20200207-master-m0455a24b30 07.02.20"; +const char _citymania_version[] = "20200207-master-m20f19618cf 07.02.20"; diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 85ede0a09d..82ec2bf9ca 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -39,6 +39,8 @@ #include "table/strings.h" +#include "citymania/highlight.hpp" + #include "safeguards.h" static void ShowRVStationPicker(Window *parent, RoadStopType rs); @@ -290,6 +292,12 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, u SB(p2, 16, 16, INVALID_STATION); // no station to join TileArea ta(start_tile, end_tile); + if (_ctrl_pressed && start_tile == end_tile && IsTileType (start_tile, MP_STATION)) { + /* Select station to join */ + citymania::SetStationToJoin(Station::GetByTile(end_tile)); + return; + } + if (ddir >= DIAGDIR_END) { if (ddir < DIAGDIR_END + 2) { SetBit(p2, 1); // It's a drive-through stop. @@ -1330,6 +1338,7 @@ struct BuildRoadStationWindow : public PickerWindowBase { this->LowerWidget(_settings_client.gui.station_show_coverage + WID_BROS_LT_OFF); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); this->SetDirty(); + citymania::MarkCoverageHighlightDirty(); break; default: diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 104a37c8e8..fcf2f16361 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -105,8 +105,8 @@ static void FindStationsAroundSelection() { /* With distant join we don't know which station will be selected, so don't show any */ if (_ctrl_pressed) { - SetViewportCatchmentStation(nullptr, true); - citymania::SetStationBiildingPossibility(citymania::BuildingPossibility::QUERY); + // SetViewportCatchmentStation(nullptr, true); + // citymania::SetStationBiildingStatus(citymania::StationBulidingStatus::JOIN); return; } @@ -121,7 +121,7 @@ static void FindStationsAroundSelection() TileArea ta(TileXY(max(0, x - max_c), max(0, y - max_c)), TileXY(min(MapMaxX(), x + location.w + max_c), min(MapMaxY(), y + location.h + max_c))); Station *adjacent = nullptr; - auto cmbp = citymania::BuildingPossibility::OK; + auto cmbp = citymania::StationBulidingStatus::NEW; /* Direct loop instead of FindStationsAroundTiles as we are not interested in catchment area */ TILE_AREA_LOOP(tile, ta) { @@ -138,7 +138,7 @@ static void FindStationsAroundSelection() } } SetViewportCatchmentStation(adjacent, true); - citymania::SetStationBiildingPossibility(cmbp); + citymania::SetStationBiildingStatus(citymania::StationBulidingStatus::JOIN); } /** @@ -148,6 +148,7 @@ static void FindStationsAroundSelection() */ void CheckRedrawStationCoverage(const Window *w) { + return; // CM has better redraw handling /* Test if ctrl state changed */ static bool _last_ctrl_pressed; if (_ctrl_pressed != _last_ctrl_pressed) { @@ -2454,18 +2455,19 @@ struct SelectStationWindow : WindowPopup { { if (widget != WID_JS_PANEL || T::EXPECTED_FACIL == FACIL_WAYPOINT) { SetViewportCatchmentStation(nullptr, true); - citymania::SetStationBiildingPossibility(citymania::BuildingPossibility::QUERY); + citymania::SetStationBiildingStatus(citymania::StationBulidingStatus::QUERY); return; } /* Show coverage area of station under cursor */ uint st_index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_JS_PANEL, WD_FRAMERECT_TOP); - citymania::SetStationBiildingPossibility(citymania::BuildingPossibility::OK); if (st_index == 0 || st_index > _stations_nearby_list.size()) { SetViewportCatchmentStation(nullptr, true); + citymania::SetStationBiildingStatus(citymania::StationBulidingStatus::NEW); } else { st_index--; SetViewportCatchmentStation(Station::Get(_stations_nearby_list[st_index]), true); + citymania::SetStationBiildingStatus(citymania::StationBulidingStatus::JOIN); } } }; @@ -2522,6 +2524,20 @@ static bool StationJoinerNeeded(const CommandContainer &cmd, TileArea ta) template void ShowSelectBaseStationIfNeeded(const CommandContainer &cmd, TileArea ta) { + // CM No need to show window anymore + auto join_to = citymania::GetStationToJoin(); + auto cmd2 = cmd; + SetBit(cmd2.p2, 2); + if (_ctrl_pressed) SB(cmd2.p2, 16, 16, NEW_STATION); + else if (join_to) SB(cmd2.p2, 16, 16, join_to->index); + else { + SB(cmd2.p2, 16, 16, INVALID_STATION); + ClrBit(cmd2.p2, 2); + } + + DoCommandP(&cmd2); + return; + if (StationJoinerNeeded(cmd, ta)) { if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); new SelectStationWindow(&_select_station_desc, cmd, ta); diff --git a/src/table/sprites.h b/src/table/sprites.h index 0c415a1dfd..d366024a0c 100644 --- a/src/table/sprites.h +++ b/src/table/sprites.h @@ -330,7 +330,9 @@ static const SpriteID PALETTE_TINT_YELLOW_WHITE = PALETTE_TINT_BASE + 7; static const SpriteID PALETTE_TINT_WHITE = PALETTE_TINT_BASE + 8; static const SpriteID PALETTE_TINT_GREEN = PALETTE_TINT_BASE + 9; static const SpriteID PALETTE_TINT_CYAN = PALETTE_TINT_BASE + 10; -static const SpriteID PALETTE_TINT_COUNT = 11; +static const SpriteID PALETTE_TINT_CYAN_WHITE = PALETTE_TINT_BASE + 11; +static const SpriteID PALETTE_TINT_BLUE = PALETTE_TINT_BASE + 12; +static const SpriteID PALETTE_TINT_COUNT = 13; /* From where can we start putting NewGRFs? */ static const SpriteID SPR_NEWGRFS_BASE = PALETTE_TINT_BASE + PALETTE_TINT_COUNT;