src/signs.cpp
branchnoai
changeset 9694 e72987579514
parent 9686 d3c195c226f9
child 9701 d1ac22c62f64
equal deleted inserted replaced
9693:31fcaa5375a1 9694:e72987579514
    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 
   195 	} else { // Delete sign
   160 	} else { // Delete sign
   196 		if (flags & DC_EXEC) {
   161 		if (flags & DC_EXEC) {
   197 			Sign *si = GetSign(p1);
   162 			Sign *si = GetSign(p1);
   198 
   163 
   199 			MarkSignDirty(si);
   164 			MarkSignDirty(si);
   200 			DeleteSign(si);
   165 			delete si;
   201 
   166 
   202 			InvalidateWindow(WC_SIGN_LIST, 0);
   167 			InvalidateWindow(WC_SIGN_LIST, 0);
   203 			_sign_sort_dirty = true;
   168 			_sign_sort_dirty = true;
   204 			_total_signs--;
   169 			_total_signs--;
   205 		}
   170 		}
   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),
   280 static void Load_SIGN()
   245 static void Load_SIGN()
   281 {
   246 {
   282 	_total_signs = 0;
   247 	_total_signs = 0;
   283 	int index;
   248 	int index;
   284 	while ((index = SlIterateArray()) != -1) {
   249 	while ((index = SlIterateArray()) != -1) {
   285 		Sign *si;
   250 		Sign *si = new (index) Sign();
   286 
       
   287 		if (!AddBlockIfNeeded(&_Sign_pool, index))
       
   288 			error("Signs: failed loading savegame: too many signs");
       
   289 
       
   290 		si = GetSign(index);
       
   291 		SlObject(si, _sign_desc);
   251 		SlObject(si, _sign_desc);
   292 
   252 
   293 		_total_signs++;
   253 		_total_signs++;
   294 	}
   254 	}
   295 
   255