2 |
2 |
3 /** @file signs.cpp */ |
3 /** @file signs.cpp */ |
4 |
4 |
5 #include "stdafx.h" |
5 #include "stdafx.h" |
6 #include "openttd.h" |
6 #include "openttd.h" |
7 #include "table/strings.h" |
|
8 #include "strings.h" |
|
9 #include "functions.h" |
|
10 #include "landscape.h" |
7 #include "landscape.h" |
11 #include "player.h" |
8 #include "player_func.h" |
12 #include "signs.h" |
9 #include "signs.h" |
13 #include "saveload.h" |
10 #include "saveload.h" |
14 #include "command.h" |
11 #include "command_func.h" |
15 #include "variables.h" |
12 #include "variables.h" |
16 #include "string.h" |
|
17 #include "misc/autoptr.hpp" |
13 #include "misc/autoptr.hpp" |
|
14 #include "strings_func.h" |
|
15 #include "viewport_func.h" |
|
16 #include "zoom_func.h" |
|
17 #include "functions.h" |
|
18 #include "window_func.h" |
|
19 #include "map_func.h" |
|
20 #include "string_func.h" |
|
21 |
|
22 #include "table/strings.h" |
18 |
23 |
19 SignID _new_sign_id; |
24 SignID _new_sign_id; |
20 uint _total_signs; |
25 uint _total_signs; |
|
26 bool _sign_sort_dirty; |
21 |
27 |
22 /* Initialize the sign-pool */ |
28 /* Initialize the sign-pool */ |
23 DEFINE_OLD_POOL_GENERIC(Sign, Sign) |
29 DEFINE_OLD_POOL_GENERIC(Sign, Sign) |
24 |
30 |
25 Sign::Sign(StringID string) |
31 Sign::Sign(PlayerID owner) |
26 { |
32 { |
27 this->str = string; |
33 this->owner = owner; |
28 } |
34 } |
29 |
35 |
30 Sign::~Sign() |
36 Sign::~Sign() |
31 { |
37 { |
32 DeleteName(this->str); |
38 free(this->name); |
33 this->str = STR_NULL; |
39 this->owner = INVALID_PLAYER; |
34 } |
40 } |
35 |
41 |
36 /** |
42 /** |
37 * |
43 * |
38 * Update the coordinate of one sign |
44 * Update the coordinate of one sign |
89 * @param p2 unused |
95 * @param p2 unused |
90 */ |
96 */ |
91 CommandCost CmdPlaceSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
97 CommandCost CmdPlaceSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
92 { |
98 { |
93 /* Try to locate a new sign */ |
99 /* Try to locate a new sign */ |
94 Sign *si = new Sign(STR_280A_SIGN); |
100 Sign *si = new Sign(_current_player); |
95 if (si == NULL) return_cmd_error(STR_2808_TOO_MANY_SIGNS); |
101 if (si == NULL) return_cmd_error(STR_2808_TOO_MANY_SIGNS); |
96 AutoPtrT<Sign> s_auto_delete = si; |
102 AutoPtrT<Sign> s_auto_delete = si; |
97 |
103 |
98 /* When we execute, really make the sign */ |
104 /* When we execute, really make the sign */ |
99 if (flags & DC_EXEC) { |
105 if (flags & DC_EXEC) { |
100 int x = TileX(tile) * TILE_SIZE; |
106 int x = TileX(tile) * TILE_SIZE; |
101 int y = TileY(tile) * TILE_SIZE; |
107 int y = TileY(tile) * TILE_SIZE; |
102 |
108 |
103 si->x = x; |
109 si->x = x; |
104 si->y = y; |
110 si->y = y; |
105 si->owner = _current_player; // owner of the sign; just eyecandy |
|
106 si->z = GetSlopeZ(x, y); |
111 si->z = GetSlopeZ(x, y); |
107 UpdateSignVirtCoords(si); |
112 UpdateSignVirtCoords(si); |
108 MarkSignDirty(si); |
113 MarkSignDirty(si); |
109 InvalidateWindow(WC_SIGN_LIST, 0); |
114 InvalidateWindow(WC_SIGN_LIST, 0); |
110 _sign_sort_dirty = true; |
115 _sign_sort_dirty = true; |
130 if (!IsValidSignID(p1)) return CMD_ERROR; |
135 if (!IsValidSignID(p1)) return CMD_ERROR; |
131 |
136 |
132 /* If _cmd_text 0 means the new text for the sign is non-empty. |
137 /* If _cmd_text 0 means the new text for the sign is non-empty. |
133 * So rename the sign. If it is empty, it has no name, so delete it */ |
138 * So rename the sign. If it is empty, it has no name, so delete it */ |
134 if (!StrEmpty(_cmd_text)) { |
139 if (!StrEmpty(_cmd_text)) { |
135 /* Create the name */ |
|
136 StringID str = AllocateName(_cmd_text, 0); |
|
137 if (str == 0) return CMD_ERROR; |
|
138 |
|
139 if (flags & DC_EXEC) { |
140 if (flags & DC_EXEC) { |
140 Sign *si = GetSign(p1); |
141 Sign *si = GetSign(p1); |
141 |
142 |
142 /* Delete the old name */ |
143 /* Delete the old name */ |
143 DeleteName(si->str); |
144 free(si->name); |
144 /* Assign the new one */ |
145 /* Assign the new one */ |
145 si->str = str; |
146 si->name = strdup(_cmd_text); |
146 si->owner = _current_player; |
147 si->owner = _current_player; |
147 |
148 |
148 /* Update; mark sign dirty twice, because it can either becom longer, or shorter */ |
149 /* Update; mark sign dirty twice, because it can either becom longer, or shorter */ |
149 MarkSignDirty(si); |
150 MarkSignDirty(si); |
150 UpdateSignVirtCoords(si); |
151 UpdateSignVirtCoords(si); |
151 MarkSignDirty(si); |
152 MarkSignDirty(si); |
152 InvalidateWindow(WC_SIGN_LIST, 0); |
153 InvalidateWindow(WC_SIGN_LIST, 0); |
153 _sign_sort_dirty = true; |
154 _sign_sort_dirty = true; |
154 } else { |
|
155 /* Free the name, because we did not assign it yet */ |
|
156 DeleteName(str); |
|
157 } |
155 } |
158 } else { // Delete sign |
156 } else { // Delete sign |
159 if (flags & DC_EXEC) { |
157 if (flags & DC_EXEC) { |
160 Sign *si = GetSign(p1); |
158 Sign *si = GetSign(p1); |
161 |
159 |
208 _Sign_pool.CleanPool(); |
206 _Sign_pool.CleanPool(); |
209 _Sign_pool.AddBlockToPool(); |
207 _Sign_pool.AddBlockToPool(); |
210 } |
208 } |
211 |
209 |
212 static const SaveLoad _sign_desc[] = { |
210 static const SaveLoad _sign_desc[] = { |
213 SLE_VAR(Sign, str, SLE_UINT16), |
211 SLE_CONDVAR(Sign, name, SLE_NAME, 0, 83), |
|
212 SLE_CONDSTR(Sign, name, SLE_STR, 0, 84, SL_MAX_VERSION), |
214 SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, 0, 4), |
213 SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, 0, 4), |
215 SLE_CONDVAR(Sign, y, SLE_FILE_I16 | SLE_VAR_I32, 0, 4), |
214 SLE_CONDVAR(Sign, y, SLE_FILE_I16 | SLE_VAR_I32, 0, 4), |
216 SLE_CONDVAR(Sign, x, SLE_INT32, 5, SL_MAX_VERSION), |
215 SLE_CONDVAR(Sign, x, SLE_INT32, 5, SL_MAX_VERSION), |
217 SLE_CONDVAR(Sign, y, SLE_INT32, 5, SL_MAX_VERSION), |
216 SLE_CONDVAR(Sign, y, SLE_INT32, 5, SL_MAX_VERSION), |
218 SLE_CONDVAR(Sign, owner, SLE_UINT8, 6, SL_MAX_VERSION), |
217 SLE_CONDVAR(Sign, owner, SLE_UINT8, 6, SL_MAX_VERSION), |