changeset 4077 | d4d440dd8925 |
parent 4052 | d6f167c6e9cb |
child 4261 | 28670f743746 |
4076:a6650b616430 | 4077:d4d440dd8925 |
---|---|
32 */ |
32 */ |
33 static void WaypointPoolNewBlock(uint start_item) |
33 static void WaypointPoolNewBlock(uint start_item) |
34 { |
34 { |
35 Waypoint *wp; |
35 Waypoint *wp; |
36 |
36 |
37 FOR_ALL_WAYPOINTS_FROM(wp, start_item) |
37 FOR_ALL_WAYPOINTS_FROM(wp, start_item) wp->index = start_item++; |
38 wp->index = start_item++; |
|
39 } |
38 } |
40 |
39 |
41 /* Initialize the town-pool */ |
40 /* Initialize the town-pool */ |
42 MemoryPool _waypoint_pool = { "Waypoints", WAYPOINT_POOL_MAX_BLOCKS, WAYPOINT_POOL_BLOCK_SIZE_BITS, sizeof(Waypoint), &WaypointPoolNewBlock, NULL, 0, 0, NULL }; |
41 MemoryPool _waypoint_pool = { "Waypoints", WAYPOINT_POOL_MAX_BLOCKS, WAYPOINT_POOL_BLOCK_SIZE_BITS, sizeof(Waypoint), &WaypointPoolNewBlock, NULL, 0, 0, NULL }; |
43 |
42 |
48 |
47 |
49 FOR_ALL_WAYPOINTS(wp) { |
48 FOR_ALL_WAYPOINTS(wp) { |
50 if (wp->xy == 0) { |
49 if (wp->xy == 0) { |
51 uint index = wp->index; |
50 uint index = wp->index; |
52 |
51 |
53 memset(wp, 0, sizeof(Waypoint)); |
52 memset(wp, 0, sizeof(*wp)); |
54 wp->index = index; |
53 wp->index = index; |
55 |
54 |
56 return wp; |
55 return wp; |
57 } |
56 } |
58 } |
57 } |
59 |
58 |
60 /* Check if we can add a block to the pool */ |
59 /* Check if we can add a block to the pool */ |
61 if (AddBlockToPool(&_waypoint_pool)) |
60 if (AddBlockToPool(&_waypoint_pool)) return AllocateWaypoint(); |
62 return AllocateWaypoint(); |
|
63 |
61 |
64 return NULL; |
62 return NULL; |
65 } |
63 } |
66 |
64 |
67 /* Update the sign for the waypoint */ |
65 /* Update the sign for the waypoint */ |
86 void UpdateAllWaypointSigns(void) |
84 void UpdateAllWaypointSigns(void) |
87 { |
85 { |
88 Waypoint *wp; |
86 Waypoint *wp; |
89 |
87 |
90 FOR_ALL_WAYPOINTS(wp) { |
88 FOR_ALL_WAYPOINTS(wp) { |
91 if (wp->xy) |
89 if (wp->xy != 0) UpdateWaypointSign(wp); |
92 UpdateWaypointSign(wp); |
|
93 } |
90 } |
94 } |
91 } |
95 |
92 |
96 /* Set the default name for a waypoint */ |
93 /* Set the default name for a waypoint */ |
97 static void MakeDefaultWaypointName(Waypoint* wp) |
94 static void MakeDefaultWaypointName(Waypoint* wp) |
104 |
101 |
105 memset(used_waypoint, 0, sizeof(used_waypoint)); |
102 memset(used_waypoint, 0, sizeof(used_waypoint)); |
106 |
103 |
107 /* Find an unused waypoint number belonging to this town */ |
104 /* Find an unused waypoint number belonging to this town */ |
108 FOR_ALL_WAYPOINTS(local_wp) { |
105 FOR_ALL_WAYPOINTS(local_wp) { |
109 if (wp == local_wp) |
106 if (wp == local_wp) continue; |
110 continue; |
|
111 |
107 |
112 if (local_wp->xy && local_wp->string == STR_NULL && local_wp->town_index == wp->town_index) |
108 if (local_wp->xy && local_wp->string == STR_NULL && local_wp->town_index == wp->town_index) |
113 used_waypoint[local_wp->town_cn] = true; |
109 used_waypoint[local_wp->town_cn] = true; |
114 } |
110 } |
115 |
111 |
122 |
118 |
123 /* Find a deleted waypoint close to a tile. */ |
119 /* Find a deleted waypoint close to a tile. */ |
124 static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile) |
120 static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile) |
125 { |
121 { |
126 Waypoint *wp, *best = NULL; |
122 Waypoint *wp, *best = NULL; |
127 uint thres = 8, cur_dist; |
123 uint thres = 8; |
128 |
124 |
129 FOR_ALL_WAYPOINTS(wp) { |
125 FOR_ALL_WAYPOINTS(wp) { |
130 if (wp->deleted && wp->xy) { |
126 if (wp->deleted && wp->xy != 0) { |
131 cur_dist = DistanceManhattan(tile, wp->xy); |
127 uint cur_dist = DistanceManhattan(tile, wp->xy); |
128 |
|
132 if (cur_dist < thres) { |
129 if (cur_dist < thres) { |
133 thres = cur_dist; |
130 thres = cur_dist; |
134 best = wp; |
131 best = wp; |
135 } |
132 } |
136 } |
133 } |
188 (axis = AXIS_Y, GetTrackBits(tile) != TRACK_BIT_Y) |
185 (axis = AXIS_Y, GetTrackBits(tile) != TRACK_BIT_Y) |
189 )) { |
186 )) { |
190 return_cmd_error(STR_1005_NO_SUITABLE_RAILROAD_TRACK); |
187 return_cmd_error(STR_1005_NO_SUITABLE_RAILROAD_TRACK); |
191 } |
188 } |
192 |
189 |
193 if (!CheckTileOwnership(tile)) |
190 if (!CheckTileOwnership(tile)) return CMD_ERROR; |
194 return CMD_ERROR; |
|
195 |
|
196 if (!EnsureNoVehicle(tile)) return CMD_ERROR; |
191 if (!EnsureNoVehicle(tile)) return CMD_ERROR; |
197 |
192 |
198 tileh = GetTileSlope(tile, NULL); |
193 tileh = GetTileSlope(tile, NULL); |
199 if (tileh != SLOPE_FLAT) { |
194 if (tileh != SLOPE_FLAT && |
200 if (!_patches.build_on_slopes || IsSteepSlope(tileh) || !(tileh & (0x3 << axis)) || !(tileh & ~(0x3 << axis))) |
195 (!_patches.build_on_slopes || IsSteepSlope(tileh) || !(tileh & (0x3 << axis)) || !(tileh & ~(0x3 << axis)))) { |
201 return_cmd_error(STR_0007_FLAT_LAND_REQUIRED); |
196 return_cmd_error(STR_0007_FLAT_LAND_REQUIRED); |
202 } |
197 } |
203 |
198 |
204 /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */ |
199 /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */ |
205 wp = FindDeletedWaypointCloseTo(tile); |
200 wp = FindDeletedWaypointCloseTo(tile); |
206 if (wp == NULL) { |
201 if (wp == NULL) { |
253 |
248 |
254 order.type = OT_GOTO_WAYPOINT; |
249 order.type = OT_GOTO_WAYPOINT; |
255 order.station = wp->index; |
250 order.station = wp->index; |
256 DeleteDestinationFromVehicleOrder(order); |
251 DeleteDestinationFromVehicleOrder(order); |
257 |
252 |
258 if (wp->string != STR_NULL) |
253 if (wp->string != STR_NULL) DeleteName(wp->string); |
259 DeleteName(wp->string); |
|
260 |
254 |
261 RedrawWaypointSign(wp); |
255 RedrawWaypointSign(wp); |
262 } |
256 } |
263 |
257 |
264 /* Daily loop for waypoints */ |
258 /* Daily loop for waypoints */ |
266 { |
260 { |
267 Waypoint *wp; |
261 Waypoint *wp; |
268 |
262 |
269 /* Check if we need to delete a waypoint */ |
263 /* Check if we need to delete a waypoint */ |
270 FOR_ALL_WAYPOINTS(wp) { |
264 FOR_ALL_WAYPOINTS(wp) { |
271 if (wp->deleted && !--wp->deleted) { |
265 if (wp->deleted != 0 && --wp->deleted == 0) DoDeleteWaypoint(wp); |
272 DoDeleteWaypoint(wp); |
|
273 } |
|
274 } |
266 } |
275 } |
267 } |
276 |
268 |
277 /* Remove a waypoint */ |
269 /* Remove a waypoint */ |
278 int32 RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove) |
270 int32 RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove) |
279 { |
271 { |
280 Waypoint *wp; |
272 Waypoint *wp; |
281 |
273 |
282 /* Make sure it's a waypoint */ |
274 /* Make sure it's a waypoint */ |
283 if (!IsTileType(tile, MP_RAILWAY) || !IsRailWaypoint(tile)) |
275 if (!IsTileType(tile, MP_RAILWAY) || |
276 !IsRailWaypoint(tile) || |
|
277 (!CheckTileOwnership(tile) && _current_player != OWNER_WATER) || |
|
278 !EnsureNoVehicle(tile)) { |
|
284 return CMD_ERROR; |
279 return CMD_ERROR; |
285 |
280 } |
286 if (!CheckTileOwnership(tile) && !(_current_player == OWNER_WATER)) |
|
287 return CMD_ERROR; |
|
288 |
|
289 if (!EnsureNoVehicle(tile)) |
|
290 return CMD_ERROR; |
|
291 |
281 |
292 if (flags & DC_EXEC) { |
282 if (flags & DC_EXEC) { |
293 wp = GetWaypointByTile(tile); |
283 wp = GetWaypointByTile(tile); |
294 |
284 |
295 wp->deleted = 30; // let it live for this many days before we do the actual deletion. |
285 wp->deleted = 30; // let it live for this many days before we do the actual deletion. |
325 * @param p2 unused |
315 * @param p2 unused |
326 */ |
316 */ |
327 int32 CmdRenameWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
317 int32 CmdRenameWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
328 { |
318 { |
329 Waypoint *wp; |
319 Waypoint *wp; |
330 StringID str; |
|
331 |
320 |
332 if (!IsWaypointIndex(p1)) return CMD_ERROR; |
321 if (!IsWaypointIndex(p1)) return CMD_ERROR; |
333 |
322 |
334 if (_cmd_text[0] != '\0') { |
323 if (_cmd_text[0] != '\0') { |
335 str = AllocateNameUnique(_cmd_text, 0); |
324 StringID str = AllocateNameUnique(_cmd_text, 0); |
336 if (str == 0) |
325 |
337 return CMD_ERROR; |
326 if (str == 0) return CMD_ERROR; |
338 |
327 |
339 if (flags & DC_EXEC) { |
328 if (flags & DC_EXEC) { |
340 wp = GetWaypoint(p1); |
329 wp = GetWaypoint(p1); |
341 if (wp->string != STR_NULL) |
330 if (wp->string != STR_NULL) DeleteName(wp->string); |
342 DeleteName(wp->string); |
|
343 |
331 |
344 wp->string = str; |
332 wp->string = str; |
345 wp->town_cn = 0; |
333 wp->town_cn = 0; |
346 |
334 |
347 UpdateWaypointSign(wp); |
335 UpdateWaypointSign(wp); |
350 DeleteName(str); |
338 DeleteName(str); |
351 } |
339 } |
352 } else { |
340 } else { |
353 if (flags & DC_EXEC) { |
341 if (flags & DC_EXEC) { |
354 wp = GetWaypoint(p1); |
342 wp = GetWaypoint(p1); |
355 if (wp->string != STR_NULL) |
343 if (wp->string != STR_NULL) DeleteName(wp->string); |
356 DeleteName(wp->string); |
|
357 |
344 |
358 MakeDefaultWaypointName(wp); |
345 MakeDefaultWaypointName(wp); |
359 UpdateWaypointSign(wp); |
346 UpdateWaypointSign(wp); |
360 MarkWholeScreenDirty(); |
347 MarkWholeScreenDirty(); |
361 } |
348 } |
393 { |
380 { |
394 Waypoint *wp; |
381 Waypoint *wp; |
395 |
382 |
396 /* Convert the old 'town_or_string', to 'string' / 'town' / 'town_cn' */ |
383 /* Convert the old 'town_or_string', to 'string' / 'town' / 'town_cn' */ |
397 FOR_ALL_WAYPOINTS(wp) { |
384 FOR_ALL_WAYPOINTS(wp) { |
398 if (wp->xy == 0) |
385 if (wp->xy == 0) continue; |
399 continue; |
|
400 |
386 |
401 wp->town_index = ClosestTownFromTile(wp->xy, (uint)-1)->index; |
387 wp->town_index = ClosestTownFromTile(wp->xy, (uint)-1)->index; |
402 wp->town_cn = 0; |
388 wp->town_cn = 0; |
403 if (wp->string & 0xC000) { |
389 if (wp->string & 0xC000) { |
404 wp->town_cn = wp->string & 0x3F; |
390 wp->town_cn = wp->string & 0x3F; |