signs.cpp

Go to the documentation of this file.
00001 /* $Id: signs.cpp 15434 2009-02-09 21:20:05Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "landscape.h"
00007 #include "company_func.h"
00008 #include "signs_base.h"
00009 #include "signs_func.h"
00010 #include "command_func.h"
00011 #include "strings_func.h"
00012 #include "viewport_func.h"
00013 #include "tilehighlight_func.h"
00014 #include "zoom_func.h"
00015 #include "functions.h"
00016 #include "window_func.h"
00017 #include "map_func.h"
00018 #include "string_func.h"
00019 #include "oldpool_func.h"
00020 
00021 #include "table/strings.h"
00022 
00023 SignID _new_sign_id;
00024 
00025 /* Initialize the sign-pool */
00026 DEFINE_OLD_POOL_GENERIC(Sign, Sign)
00027 
00028 Sign::Sign(Owner owner)
00029 {
00030   this->owner = owner;
00031 }
00032 
00033 Sign::~Sign()
00034 {
00035   free(this->name);
00036 
00037   if (CleaningPool()) return;
00038 
00039   DeleteRenameSignWindow(this->index);
00040   this->owner = INVALID_OWNER;
00041 }
00042 
00049 static void UpdateSignVirtCoords(Sign *si)
00050 {
00051   Point pt = RemapCoords(si->x, si->y, si->z);
00052   SetDParam(0, si->index);
00053   UpdateViewportSignPos(&si->sign, pt.x, pt.y - 6, STR_2806);
00054 }
00055 
00057 void UpdateAllSignVirtCoords()
00058 {
00059   Sign *si;
00060 
00061   FOR_ALL_SIGNS(si) UpdateSignVirtCoords(si);
00062 }
00063 
00072 static void MarkSignDirty(Sign *si)
00073 {
00074   /* We use ZOOM_LVL_MAX here, as every viewport can have an other zoom,
00075     *  and there is no way for us to know which is the biggest. So make the
00076     *  biggest area dirty, and we are safe for sure. */
00077   MarkAllViewportsDirty(
00078     si->sign.left - 6,
00079     si->sign.top  - 3,
00080     si->sign.left + ScaleByZoom(si->sign.width_1 + 12, ZOOM_LVL_MAX),
00081     si->sign.top  + ScaleByZoom(12, ZOOM_LVL_MAX));
00082 }
00083 
00093 CommandCost CmdPlaceSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
00094 {
00095   /* Try to locate a new sign */
00096   if (!Sign::CanAllocateItem()) return_cmd_error(STR_2808_TOO_MANY_SIGNS);
00097 
00098   /* Check sign text length if any */
00099   if (!StrEmpty(text) && strlen(text) >= MAX_LENGTH_SIGN_NAME_BYTES) return CMD_ERROR;
00100 
00101   /* When we execute, really make the sign */
00102   if (flags & DC_EXEC) {
00103     Sign *si = new Sign(_current_company);
00104     int x = TileX(tile) * TILE_SIZE;
00105     int y = TileY(tile) * TILE_SIZE;
00106 
00107     si->x = x;
00108     si->y = y;
00109     si->z = GetSlopeZ(x, y);
00110     if (!StrEmpty(text)) {
00111       si->name = strdup(text);
00112     }
00113     UpdateSignVirtCoords(si);
00114     MarkSignDirty(si);
00115     InvalidateWindowData(WC_SIGN_LIST, 0, 0);
00116     _new_sign_id = si->index;
00117   }
00118 
00119   return CommandCost();
00120 }
00121 
00131 CommandCost CmdRenameSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
00132 {
00133   if (!IsValidSignID(p1)) return CMD_ERROR;
00134 
00135   /* Rename the signs when empty, otherwise remove it */
00136   if (!StrEmpty(text)) {
00137     if (strlen(text) >= MAX_LENGTH_SIGN_NAME_BYTES) return CMD_ERROR;
00138 
00139     if (flags & DC_EXEC) {
00140       Sign *si = GetSign(p1);
00141 
00142       /* Delete the old name */
00143       free(si->name);
00144       /* Assign the new one */
00145       si->name = strdup(text);
00146       si->owner = _current_company;
00147 
00148       /* Update; mark sign dirty twice, because it can either becom longer, or shorter */
00149       MarkSignDirty(si);
00150       UpdateSignVirtCoords(si);
00151       MarkSignDirty(si);
00152       InvalidateWindowData(WC_SIGN_LIST, 0, 1);
00153     }
00154   } else { // Delete sign
00155     if (flags & DC_EXEC) {
00156       Sign *si = GetSign(p1);
00157 
00158       MarkSignDirty(si);
00159       delete si;
00160 
00161       InvalidateWindowData(WC_SIGN_LIST, 0, 0);
00162     }
00163   }
00164 
00165   return CommandCost();
00166 }
00167 
00175 void CcPlaceSign(bool success, TileIndex tile, uint32 p1, uint32 p2)
00176 {
00177   if (success) {
00178     ShowRenameSignWindow(GetSign(_new_sign_id));
00179     ResetObjectToPlace();
00180   }
00181 }
00182 
00189 void PlaceProc_Sign(TileIndex tile)
00190 {
00191   DoCommandP(tile, 0, 0, CMD_PLACE_SIGN | CMD_MSG(STR_2809_CAN_T_PLACE_SIGN_HERE), CcPlaceSign);
00192 }
00193 
00199 void InitializeSigns()
00200 {
00201   _Sign_pool.CleanPool();
00202   _Sign_pool.AddBlockToPool();
00203 }

Generated on Mon Mar 9 23:33:50 2009 for openttd by  doxygen 1.5.6