11 #include "player.h" |
11 #include "player.h" |
12 #include "signs.h" |
12 #include "signs.h" |
13 #include "saveload.h" |
13 #include "saveload.h" |
14 #include "command.h" |
14 #include "command.h" |
15 #include "variables.h" |
15 #include "variables.h" |
|
16 #include "misc/autoptr.hpp" |
16 |
17 |
17 SignID _new_sign_id; |
18 SignID _new_sign_id; |
18 uint _total_signs; |
19 uint _total_signs; |
19 |
20 |
20 /** |
|
21 * Called if a new block is added to the sign-pool |
|
22 */ |
|
23 static void SignPoolNewBlock(uint start_item) |
|
24 { |
|
25 Sign *si; |
|
26 |
|
27 /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. |
|
28 * TODO - This is just a temporary stage, this will be removed. */ |
|
29 for (si = GetSign(start_item); si != NULL; si = (si->index + 1U < GetSignPoolSize()) ? GetSign(si->index + 1U) : NULL) si->index = start_item++; |
|
30 } |
|
31 |
|
32 /* Initialize the sign-pool */ |
21 /* Initialize the sign-pool */ |
33 DEFINE_OLD_POOL(Sign, Sign, SignPoolNewBlock, NULL) |
22 DEFINE_OLD_POOL_GENERIC(Sign, Sign) |
|
23 |
|
24 Sign::Sign(StringID string) |
|
25 { |
|
26 this->str = string; |
|
27 } |
|
28 |
|
29 Sign::~Sign() |
|
30 { |
|
31 this->QuickFree(); |
|
32 this->str = STR_NULL; |
|
33 } |
|
34 |
|
35 void Sign::QuickFree() |
|
36 { |
|
37 DeleteName(this->str); |
|
38 } |
34 |
39 |
35 /** |
40 /** |
36 * |
41 * |
37 * Update the coordinate of one sign |
42 * Update the coordinate of one sign |
38 * @param si Pointer to the Sign |
43 * @param si Pointer to the Sign |
75 si->sign.left + ScaleByZoom(si->sign.width_1 + 12, ZOOM_LVL_MAX), |
80 si->sign.left + ScaleByZoom(si->sign.width_1 + 12, ZOOM_LVL_MAX), |
76 si->sign.top + ScaleByZoom(12, ZOOM_LVL_MAX)); |
81 si->sign.top + ScaleByZoom(12, ZOOM_LVL_MAX)); |
77 } |
82 } |
78 |
83 |
79 /** |
84 /** |
80 * |
|
81 * Allocates a new sign |
|
82 * |
|
83 * @return The pointer to the new sign, or NULL if there is no more free space |
|
84 */ |
|
85 static Sign *AllocateSign() |
|
86 { |
|
87 Sign *si; |
|
88 |
|
89 /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. |
|
90 * TODO - This is just a temporary stage, this will be removed. */ |
|
91 for (si = GetSign(0); si != NULL; si = (si->index + 1U < GetSignPoolSize()) ? GetSign(si->index + 1U) : NULL) { |
|
92 if (!IsValidSign(si)) { |
|
93 uint index = si->index; |
|
94 |
|
95 memset(si, 0, sizeof(Sign)); |
|
96 si->index = index; |
|
97 |
|
98 return si; |
|
99 } |
|
100 } |
|
101 |
|
102 /* Check if we can add a block to the pool */ |
|
103 if (AddBlockToPool(&_Sign_pool)) |
|
104 return AllocateSign(); |
|
105 |
|
106 return NULL; |
|
107 } |
|
108 |
|
109 /** |
|
110 * Destroy a sign placed on the map |
|
111 * @param si Pointer to the Sign to remove |
|
112 */ |
|
113 void DestroySign(Sign *si) |
|
114 { |
|
115 DeleteName(si->str); |
|
116 } |
|
117 |
|
118 /** |
|
119 * Place a sign at the given coordinates. Ownership of sign has |
85 * Place a sign at the given coordinates. Ownership of sign has |
120 * no effect whatsoever except for the colour the sign gets for easy recognition, |
86 * no effect whatsoever except for the colour the sign gets for easy recognition, |
121 * but everybody is able to rename/remove it. |
87 * but everybody is able to rename/remove it. |
122 * @param tile tile to place sign at |
88 * @param tile tile to place sign at |
123 * @param flags type of operation |
89 * @param flags type of operation |
124 * @param p1 unused |
90 * @param p1 unused |
125 * @param p2 unused |
91 * @param p2 unused |
126 */ |
92 */ |
127 CommandCost CmdPlaceSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
93 CommandCost CmdPlaceSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
128 { |
94 { |
129 Sign *si; |
|
130 |
|
131 /* Try to locate a new sign */ |
95 /* Try to locate a new sign */ |
132 si = AllocateSign(); |
96 Sign *si = new Sign(STR_280A_SIGN); |
133 if (si == NULL) return_cmd_error(STR_2808_TOO_MANY_SIGNS); |
97 if (si == NULL) return_cmd_error(STR_2808_TOO_MANY_SIGNS); |
|
98 AutoPtrT<Sign> s_auto_delete = si; |
134 |
99 |
135 /* When we execute, really make the sign */ |
100 /* When we execute, really make the sign */ |
136 if (flags & DC_EXEC) { |
101 if (flags & DC_EXEC) { |
137 int x = TileX(tile) * TILE_SIZE; |
102 int x = TileX(tile) * TILE_SIZE; |
138 int y = TileY(tile) * TILE_SIZE; |
103 int y = TileY(tile) * TILE_SIZE; |
139 |
104 |
140 si->str = STR_280A_SIGN; |
|
141 si->x = x; |
105 si->x = x; |
142 si->y = y; |
106 si->y = y; |
143 si->owner = _current_player; // owner of the sign; just eyecandy |
107 si->owner = _current_player; // owner of the sign; just eyecandy |
144 si->z = GetSlopeZ(x, y); |
108 si->z = GetSlopeZ(x, y); |
145 UpdateSignVirtCoords(si); |
109 UpdateSignVirtCoords(si); |
146 MarkSignDirty(si); |
110 MarkSignDirty(si); |
147 InvalidateWindow(WC_SIGN_LIST, 0); |
111 InvalidateWindow(WC_SIGN_LIST, 0); |
148 _sign_sort_dirty = true; |
112 _sign_sort_dirty = true; |
149 _new_sign_id = si->index; |
113 _new_sign_id = si->index; |
150 _total_signs++; |
114 _total_signs++; |
|
115 s_auto_delete.Detach(); |
151 } |
116 } |
152 |
117 |
153 return CommandCost(); |
118 return CommandCost(); |
154 } |
119 } |
155 |
120 |
240 * |
205 * |
241 */ |
206 */ |
242 void InitializeSigns() |
207 void InitializeSigns() |
243 { |
208 { |
244 _total_signs = 0; |
209 _total_signs = 0; |
245 CleanPool(&_Sign_pool); |
210 _Sign_pool.CleanPool(); |
246 AddBlockToPool(&_Sign_pool); |
211 _Sign_pool.AddBlockToPool(); |
247 } |
212 } |
248 |
213 |
249 static const SaveLoad _sign_desc[] = { |
214 static const SaveLoad _sign_desc[] = { |
250 SLE_VAR(Sign, str, SLE_UINT16), |
215 SLE_VAR(Sign, str, SLE_UINT16), |
251 SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, 0, 4), |
216 SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, 0, 4), |