2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
2010-05-29 07:25:38 +00:00
# include <base/math.h>
2008-08-14 17:19:13 +00:00
2011-02-18 10:41:27 +00:00
# include <engine/client.h>
2010-05-29 07:25:38 +00:00
# include <engine/graphics.h>
# include <engine/textrender.h>
2009-10-27 14:38:53 +00:00
2011-04-19 08:34:51 +00:00
# include "editor.h"
2020-09-26 19:41:58 +00:00
# include <game/client/render.h>
2010-06-05 21:36:52 +00:00
2011-04-09 06:41:31 +00:00
# include <engine/input.h>
# include <engine/keys.h>
2010-05-29 07:25:38 +00:00
CLayerTiles : : CLayerTiles ( int w , int h )
2008-01-12 12:27:55 +00:00
{
2010-05-29 07:25:38 +00:00
m_Type = LAYERTYPE_TILES ;
2019-03-24 01:44:33 +00:00
m_aName [ 0 ] = ' \0 ' ;
2010-05-29 07:25:38 +00:00
m_Width = w ;
m_Height = h ;
m_Image = - 1 ;
m_Game = 0 ;
2011-01-04 10:38:14 +00:00
m_Color . r = 255 ;
m_Color . g = 255 ;
m_Color . b = 255 ;
m_Color . a = 255 ;
2011-07-18 10:05:12 +00:00
m_ColorEnv = - 1 ;
m_ColorEnvOffset = 0 ;
2011-04-13 18:37:12 +00:00
2010-09-30 21:31:19 +00:00
m_Tele = 0 ;
m_Speedup = 0 ;
m_Front = 0 ;
m_Switch = 0 ;
2014-03-12 22:34:30 +00:00
m_Tune = 0 ;
2018-10-03 16:16:58 +00:00
m_AutoMapperConfig = - 1 ;
m_Seed = 0 ;
m_AutoAutoMap = false ;
2011-04-09 06:41:31 +00:00
2020-09-26 19:41:58 +00:00
m_pTiles = new CTile [ m_Width * m_Height ] ;
2020-10-05 17:03:14 +00:00
mem_zero ( m_pTiles , ( size_t ) m_Width * m_Height * sizeof ( CTile ) ) ;
2008-01-12 12:27:55 +00:00
}
2010-05-29 07:25:38 +00:00
CLayerTiles : : ~ CLayerTiles ( )
2008-01-12 12:27:55 +00:00
{
2020-09-26 19:41:58 +00:00
delete [ ] m_pTiles ;
2008-01-12 12:27:55 +00:00
}
2016-04-30 23:47:29 +00:00
CTile CLayerTiles : : GetTile ( int x , int y )
2015-11-14 23:00:43 +00:00
{
2020-09-26 19:41:58 +00:00
return m_pTiles [ y * m_Width + x ] ;
2015-11-14 23:00:43 +00:00
}
2016-04-30 23:47:29 +00:00
void CLayerTiles : : SetTile ( int x , int y , CTile tile )
2015-11-14 23:00:43 +00:00
{
2020-09-26 19:41:58 +00:00
m_pTiles [ y * m_Width + x ] = tile ;
2015-11-14 23:00:43 +00:00
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : PrepareForSave ( )
2008-03-29 11:44:03 +00:00
{
2010-05-29 07:25:38 +00:00
for ( int y = 0 ; y < m_Height ; y + + )
for ( int x = 0 ; x < m_Width ; x + + )
2020-09-26 19:41:58 +00:00
m_pTiles [ y * m_Width + x ] . m_Flags & = TILEFLAG_VFLIP | TILEFLAG_HFLIP | TILEFLAG_ROTATE ;
2008-03-29 11:44:03 +00:00
2011-01-04 10:38:14 +00:00
if ( m_Image ! = - 1 & & m_Color . a = = 255 )
2008-03-29 11:44:03 +00:00
{
2010-05-29 07:25:38 +00:00
for ( int y = 0 ; y < m_Height ; y + + )
for ( int x = 0 ; x < m_Width ; x + + )
2022-06-11 19:38:18 +00:00
m_pTiles [ y * m_Width + x ] . m_Flags | = m_pEditor - > m_Map . m_vpImages [ m_Image ] - > m_aTileFlags [ m_pTiles [ y * m_Width + x ] . m_Index ] ;
2008-03-29 11:44:03 +00:00
}
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : MakePalette ( )
2008-01-12 12:27:55 +00:00
{
2010-05-29 07:25:38 +00:00
for ( int y = 0 ; y < m_Height ; y + + )
for ( int x = 0 ; x < m_Width ; x + + )
2020-09-26 19:41:58 +00:00
m_pTiles [ y * m_Width + x ] . m_Index = y * 16 + x ;
2008-01-12 12:27:55 +00:00
}
2018-08-19 17:05:42 +00:00
void CLayerTiles : : Render ( bool Tileset )
2008-01-12 12:27:55 +00:00
{
2022-06-11 19:38:18 +00:00
if ( m_Image > = 0 & & ( size_t ) m_Image < m_pEditor - > m_Map . m_vpImages . size ( ) )
m_Texture = m_pEditor - > m_Map . m_vpImages [ m_Image ] - > m_Texture ;
2012-08-12 10:41:50 +00:00
Graphics ( ) - > TextureSet ( m_Texture ) ;
2020-09-26 19:41:58 +00:00
ColorRGBA Color = ColorRGBA ( m_Color . r / 255.0f , m_Color . g / 255.0f , m_Color . b / 255.0f , m_Color . a / 255.0f ) ;
2012-08-13 10:57:40 +00:00
Graphics ( ) - > BlendNone ( ) ;
m_pEditor - > RenderTools ( ) - > RenderTilemap ( m_pTiles , m_Width , m_Height , 32.0f , Color , LAYERRENDERFLAG_OPAQUE ,
2020-09-26 19:41:58 +00:00
m_pEditor - > EnvelopeEval , m_pEditor , m_ColorEnv , m_ColorEnvOffset ) ;
2012-08-13 10:57:40 +00:00
Graphics ( ) - > BlendNormal ( ) ;
m_pEditor - > RenderTools ( ) - > RenderTilemap ( m_pTiles , m_Width , m_Height , 32.0f , Color , LAYERRENDERFLAG_TRANSPARENT ,
2020-09-26 19:41:58 +00:00
m_pEditor - > EnvelopeEval , m_pEditor , m_ColorEnv , m_ColorEnvOffset ) ;
2011-04-09 06:41:31 +00:00
// Render DDRace Layers
2018-08-19 17:05:42 +00:00
if ( ! Tileset )
{
if ( m_Tele )
2020-09-26 19:41:58 +00:00
m_pEditor - > RenderTools ( ) - > RenderTeleOverlay ( ( ( CLayerTele * ) this ) - > m_pTeleTile , m_Width , m_Height , 32.0f ) ;
2018-08-19 17:05:42 +00:00
if ( m_Speedup )
2020-09-26 19:41:58 +00:00
m_pEditor - > RenderTools ( ) - > RenderSpeedupOverlay ( ( ( CLayerSpeedup * ) this ) - > m_pSpeedupTile , m_Width , m_Height , 32.0f ) ;
2018-08-19 17:05:42 +00:00
if ( m_Switch )
2020-09-26 19:41:58 +00:00
m_pEditor - > RenderTools ( ) - > RenderSwitchOverlay ( ( ( CLayerSwitch * ) this ) - > m_pSwitchTile , m_Width , m_Height , 32.0f ) ;
2018-08-19 17:05:42 +00:00
if ( m_Tune )
2020-09-26 19:41:58 +00:00
m_pEditor - > RenderTools ( ) - > RenderTuneOverlay ( ( ( CLayerTune * ) this ) - > m_pTuneTile , m_Width , m_Height , 32.0f ) ;
2018-08-19 17:05:42 +00:00
}
2008-01-12 12:27:55 +00:00
}
2020-09-26 19:41:58 +00:00
int CLayerTiles : : ConvertX ( float x ) const { return ( int ) ( x / 32.0f ) ; }
int CLayerTiles : : ConvertY ( float y ) const { return ( int ) ( y / 32.0f ) ; }
2008-01-12 12:27:55 +00:00
2010-05-29 07:25:38 +00:00
void CLayerTiles : : Convert ( CUIRect Rect , RECTi * pOut )
2008-01-12 12:27:55 +00:00
{
2010-05-29 07:25:38 +00:00
pOut - > x = ConvertX ( Rect . x ) ;
pOut - > y = ConvertY ( Rect . y ) ;
2020-09-26 19:41:58 +00:00
pOut - > w = ConvertX ( Rect . x + Rect . w + 31 ) - pOut - > x ;
pOut - > h = ConvertY ( Rect . y + Rect . h + 31 ) - pOut - > y ;
2008-01-12 12:27:55 +00:00
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : Snap ( CUIRect * pRect )
2008-01-12 12:27:55 +00:00
{
2010-05-29 07:25:38 +00:00
RECTi Out ;
Convert ( * pRect , & Out ) ;
2020-09-26 19:41:58 +00:00
pRect - > x = Out . x * 32.0f ;
pRect - > y = Out . y * 32.0f ;
pRect - > w = Out . w * 32.0f ;
pRect - > h = Out . h * 32.0f ;
2008-01-12 12:27:55 +00:00
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : Clamp ( RECTi * pRect )
2008-01-12 12:27:55 +00:00
{
2010-05-29 07:25:38 +00:00
if ( pRect - > x < 0 )
2008-01-12 12:27:55 +00:00
{
2010-05-29 07:25:38 +00:00
pRect - > w + = pRect - > x ;
pRect - > x = 0 ;
2008-01-12 12:27:55 +00:00
}
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
if ( pRect - > y < 0 )
2008-01-12 12:27:55 +00:00
{
2010-05-29 07:25:38 +00:00
pRect - > h + = pRect - > y ;
pRect - > y = 0 ;
2008-01-12 12:27:55 +00:00
}
2011-04-13 18:37:12 +00:00
2020-09-26 19:41:58 +00:00
if ( pRect - > x + pRect - > w > m_Width )
2010-05-29 07:25:38 +00:00
pRect - > w = m_Width - pRect - > x ;
2008-01-12 12:27:55 +00:00
2020-09-26 19:41:58 +00:00
if ( pRect - > y + pRect - > h > m_Height )
2010-05-29 07:25:38 +00:00
pRect - > h = m_Height - pRect - > y ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
if ( pRect - > h < 0 )
pRect - > h = 0 ;
if ( pRect - > w < 0 )
pRect - > w = 0 ;
2008-01-12 12:27:55 +00:00
}
2019-03-26 18:15:24 +00:00
bool CLayerTiles : : IsEmpty ( CLayerTiles * pLayer )
{
for ( int y = 0 ; y < pLayer - > m_Height ; y + + )
for ( int x = 0 ; x < pLayer - > m_Width ; x + + )
{
int Index = pLayer - > GetTile ( x , y ) . m_Index ;
if ( Index )
{
if ( pLayer - > m_Game )
{
if ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidGameTile ( Index ) )
return false ;
}
else if ( pLayer - > m_Front )
{
if ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidFrontTile ( Index ) )
return false ;
}
else
return false ;
}
}
return true ;
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : BrushSelecting ( CUIRect Rect )
2008-01-12 12:27:55 +00:00
{
2012-08-12 10:41:50 +00:00
Graphics ( ) - > TextureClear ( ) ;
2010-05-29 07:25:38 +00:00
m_pEditor - > Graphics ( ) - > QuadsBegin ( ) ;
m_pEditor - > Graphics ( ) - > SetColor ( 1.0f , 1.0f , 1.0f , 0.4f ) ;
Snap ( & Rect ) ;
IGraphics : : CQuadItem QuadItem ( Rect . x , Rect . y , Rect . w , Rect . h ) ;
m_pEditor - > Graphics ( ) - > QuadsDrawTL ( & QuadItem , 1 ) ;
m_pEditor - > Graphics ( ) - > QuadsEnd ( ) ;
char aBuf [ 16 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " %d,%d " , ConvertX ( Rect . w ) , ConvertY ( Rect . h ) ) ;
2022-06-13 16:28:13 +00:00
TextRender ( ) - > Text ( nullptr , Rect . x + 3.0f , Rect . y + 3.0f , m_pEditor - > m_ShowPicker ? 15.0f : 15.0f * m_pEditor - > m_WorldZoom , aBuf , - 1.0f ) ;
2008-01-12 12:27:55 +00:00
}
2010-05-29 07:25:38 +00:00
int CLayerTiles : : BrushGrab ( CLayerGroup * pBrush , CUIRect Rect )
2008-01-12 12:27:55 +00:00
{
RECTi r ;
2010-05-29 07:25:38 +00:00
Convert ( Rect , & r ) ;
Clamp ( & r ) ;
2011-04-13 18:37:12 +00:00
2008-01-12 12:27:55 +00:00
if ( ! r . w | | ! r . h )
return 0 ;
2011-04-13 18:37:12 +00:00
2008-01-12 12:27:55 +00:00
// create new layers
2018-08-19 17:05:42 +00:00
if ( this - > m_Tele )
2010-09-30 21:31:19 +00:00
{
CLayerTele * pGrabbed = new CLayerTele ( r . w , r . h ) ;
pGrabbed - > m_pEditor = m_pEditor ;
2012-08-12 10:41:50 +00:00
pGrabbed - > m_Texture = m_Texture ;
2010-09-30 21:31:19 +00:00
pGrabbed - > m_Image = m_Image ;
pGrabbed - > m_Game = m_Game ;
2020-09-26 19:41:58 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
2018-09-11 08:35:02 +00:00
{
pGrabbed - > m_Color = m_Color ;
pGrabbed - > m_Color . a = 255 ;
}
2010-09-30 21:31:19 +00:00
pBrush - > AddLayer ( pGrabbed ) ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
// copy the tiles
for ( int y = 0 ; y < r . h ; y + + )
for ( int x = 0 ; x < r . w ; x + + )
2020-09-26 19:41:58 +00:00
pGrabbed - > m_pTiles [ y * pGrabbed - > m_Width + x ] = GetTile ( r . x + x , r . y + y ) ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
// copy the tele data
2016-04-30 18:11:26 +00:00
if ( ! m_pEditor - > Input ( ) - > KeyIsPressed ( KEY_SPACE ) )
2010-09-30 21:31:19 +00:00
for ( int y = 0 ; y < r . h ; y + + )
for ( int x = 0 ; x < r . w ; x + + )
{
2020-09-26 19:41:58 +00:00
pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] = ( ( CLayerTele * ) this ) - > m_pTeleTile [ ( r . y + y ) * m_Width + ( r . x + x ) ] ;
if ( pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_TELEIN | | pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_TELEOUT | | pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_TELEINEVIL
// || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELECHECKINEVIL
| | pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_TELECHECK | | pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_TELECHECKOUT
// || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELECHECKIN
| | pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_TELEINWEAPON | | pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_TELEINHOOK )
2020-05-15 22:42:11 +00:00
{
2020-09-26 19:41:58 +00:00
m_pEditor - > m_TeleNumber = pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] . m_Number ;
2020-05-15 22:42:11 +00:00
}
2010-09-30 21:31:19 +00:00
}
2010-12-07 15:51:59 +00:00
pGrabbed - > m_TeleNum = m_pEditor - > m_TeleNumber ;
2010-12-19 14:10:42 +00:00
str_copy ( pGrabbed - > m_aFileName , m_pEditor - > m_aFileName , sizeof ( pGrabbed - > m_aFileName ) ) ;
2010-09-30 21:31:19 +00:00
}
2018-08-19 17:05:42 +00:00
else if ( this - > m_Speedup )
2010-09-30 21:31:19 +00:00
{
CLayerSpeedup * pGrabbed = new CLayerSpeedup ( r . w , r . h ) ;
pGrabbed - > m_pEditor = m_pEditor ;
2012-08-12 10:41:50 +00:00
pGrabbed - > m_Texture = m_Texture ;
2010-09-30 21:31:19 +00:00
pGrabbed - > m_Image = m_Image ;
pGrabbed - > m_Game = m_Game ;
2020-09-26 19:41:58 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
2018-09-11 08:35:02 +00:00
{
pGrabbed - > m_Color = m_Color ;
pGrabbed - > m_Color . a = 255 ;
}
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
pBrush - > AddLayer ( pGrabbed ) ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
// copy the tiles
for ( int y = 0 ; y < r . h ; y + + )
for ( int x = 0 ; x < r . w ; x + + )
2020-09-26 19:41:58 +00:00
pGrabbed - > m_pTiles [ y * pGrabbed - > m_Width + x ] = GetTile ( r . x + x , r . y + y ) ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
// copy the speedup data
2016-04-30 18:11:26 +00:00
if ( ! m_pEditor - > Input ( ) - > KeyIsPressed ( KEY_SPACE ) )
2010-09-30 21:31:19 +00:00
for ( int y = 0 ; y < r . h ; y + + )
for ( int x = 0 ; x < r . w ; x + + )
{
2020-09-26 19:41:58 +00:00
pGrabbed - > m_pSpeedupTile [ y * pGrabbed - > m_Width + x ] = ( ( CLayerSpeedup * ) this ) - > m_pSpeedupTile [ ( r . y + y ) * m_Width + ( r . x + x ) ] ;
if ( pGrabbed - > m_pSpeedupTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_BOOST )
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
m_pEditor - > m_SpeedupAngle = pGrabbed - > m_pSpeedupTile [ y * pGrabbed - > m_Width + x ] . m_Angle ;
m_pEditor - > m_SpeedupForce = pGrabbed - > m_pSpeedupTile [ y * pGrabbed - > m_Width + x ] . m_Force ;
m_pEditor - > m_SpeedupMaxSpeed = pGrabbed - > m_pSpeedupTile [ y * pGrabbed - > m_Width + x ] . m_MaxSpeed ;
2010-09-30 21:31:19 +00:00
}
}
2010-12-04 11:54:53 +00:00
pGrabbed - > m_SpeedupForce = m_pEditor - > m_SpeedupForce ;
pGrabbed - > m_SpeedupMaxSpeed = m_pEditor - > m_SpeedupMaxSpeed ;
pGrabbed - > m_SpeedupAngle = m_pEditor - > m_SpeedupAngle ;
2010-12-19 14:10:42 +00:00
str_copy ( pGrabbed - > m_aFileName , m_pEditor - > m_aFileName , sizeof ( pGrabbed - > m_aFileName ) ) ;
2010-09-30 21:31:19 +00:00
}
2018-08-19 17:05:42 +00:00
else if ( this - > m_Switch )
2010-09-30 21:31:19 +00:00
{
CLayerSwitch * pGrabbed = new CLayerSwitch ( r . w , r . h ) ;
pGrabbed - > m_pEditor = m_pEditor ;
2012-08-12 10:41:50 +00:00
pGrabbed - > m_Texture = m_Texture ;
2010-09-30 21:31:19 +00:00
pGrabbed - > m_Image = m_Image ;
pGrabbed - > m_Game = m_Game ;
2020-09-26 19:41:58 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
2018-09-11 08:35:02 +00:00
{
pGrabbed - > m_Color = m_Color ;
pGrabbed - > m_Color . a = 255 ;
}
2010-09-30 21:31:19 +00:00
pBrush - > AddLayer ( pGrabbed ) ;
// copy the tiles
for ( int y = 0 ; y < r . h ; y + + )
for ( int x = 0 ; x < r . w ; x + + )
2020-09-26 19:41:58 +00:00
pGrabbed - > m_pTiles [ y * pGrabbed - > m_Width + x ] = GetTile ( r . x + x , r . y + y ) ;
2010-09-30 21:31:19 +00:00
// copy the switch data
2016-04-30 18:11:26 +00:00
if ( ! m_pEditor - > Input ( ) - > KeyIsPressed ( KEY_SPACE ) )
2010-09-30 21:31:19 +00:00
for ( int y = 0 ; y < r . h ; y + + )
for ( int x = 0 ; x < r . w ; x + + )
{
2020-09-14 14:00:32 +00:00
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] = ( ( CLayerSwitch * ) this ) - > m_pSwitchTile [ ( r . y + y ) * m_Width + ( r . x + x ) ] ;
if ( pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = ENTITY_DOOR + ENTITY_OFFSET | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_HIT_ENABLE | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_HIT_DISABLE | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_SWITCHOPEN | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_SWITCHCLOSE | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_SWITCHTIMEDOPEN | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_SWITCHTIMEDCLOSE | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = ENTITY_LASER_LONG + ENTITY_OFFSET | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = ENTITY_LASER_MEDIUM + ENTITY_OFFSET | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = ENTITY_LASER_SHORT + ENTITY_OFFSET | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_JUMP | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_ADD_TIME | |
2021-02-01 13:55:26 +00:00
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_SUBTRACT_TIME | |
2020-09-14 14:00:32 +00:00
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_ALLOW_TELE_GUN | |
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_ALLOW_BLUE_TELE_GUN )
2010-11-22 20:43:22 +00:00
{
2020-09-26 19:41:58 +00:00
m_pEditor - > m_SwitchNum = pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Number ;
m_pEditor - > m_SwitchDelay = pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Delay ;
2010-11-22 20:43:22 +00:00
}
2010-09-30 21:31:19 +00:00
}
2010-12-07 15:51:59 +00:00
pGrabbed - > m_SwitchNumber = m_pEditor - > m_SwitchNum ;
2010-12-04 11:54:53 +00:00
pGrabbed - > m_SwitchDelay = m_pEditor - > m_SwitchDelay ;
2010-12-19 14:10:42 +00:00
str_copy ( pGrabbed - > m_aFileName , m_pEditor - > m_aFileName , sizeof ( pGrabbed - > m_aFileName ) ) ;
2010-09-30 21:31:19 +00:00
}
2015-07-09 00:08:14 +00:00
2018-08-19 17:05:42 +00:00
else if ( this - > m_Tune )
2015-11-14 23:00:43 +00:00
{
2014-03-12 22:34:30 +00:00
CLayerTune * pGrabbed = new CLayerTune ( r . w , r . h ) ;
pGrabbed - > m_pEditor = m_pEditor ;
2012-08-12 10:41:50 +00:00
pGrabbed - > m_Texture = m_Texture ;
2014-03-12 22:34:30 +00:00
pGrabbed - > m_Image = m_Image ;
pGrabbed - > m_Game = m_Game ;
2020-09-26 19:41:58 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
2018-09-11 08:35:02 +00:00
{
pGrabbed - > m_Color = m_Color ;
pGrabbed - > m_Color . a = 255 ;
}
2018-08-09 10:07:49 +00:00
2014-03-12 22:34:30 +00:00
pBrush - > AddLayer ( pGrabbed ) ;
2015-07-09 00:08:14 +00:00
2014-03-12 22:34:30 +00:00
// copy the tiles
2015-11-14 23:00:43 +00:00
for ( int y = 0 ; y < r . h ; y + + )
for ( int x = 0 ; x < r . w ; x + + )
2020-09-26 19:41:58 +00:00
pGrabbed - > m_pTiles [ y * pGrabbed - > m_Width + x ] = GetTile ( r . x + x , r . y + y ) ;
2014-03-12 22:34:30 +00:00
// copy the tiles
2016-04-30 18:11:26 +00:00
if ( ! m_pEditor - > Input ( ) - > KeyIsPressed ( KEY_SPACE ) )
2015-11-14 23:00:43 +00:00
for ( int y = 0 ; y < r . h ; y + + )
for ( int x = 0 ; x < r . w ; x + + )
{
2020-09-14 14:00:32 +00:00
pGrabbed - > m_pTuneTile [ y * pGrabbed - > m_Width + x ] = ( ( CLayerTune * ) this ) - > m_pTuneTile [ ( r . y + y ) * m_Width + ( r . x + x ) ] ;
if ( pGrabbed - > m_pTuneTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_TUNE )
2015-11-14 23:00:43 +00:00
{
2020-09-26 19:41:58 +00:00
m_pEditor - > m_TuningNum = pGrabbed - > m_pTuneTile [ y * pGrabbed - > m_Width + x ] . m_Number ;
2015-11-14 23:00:43 +00:00
}
}
pGrabbed - > m_TuningNumber = m_pEditor - > m_TuningNum ;
str_copy ( pGrabbed - > m_aFileName , m_pEditor - > m_aFileName , sizeof ( pGrabbed - > m_aFileName ) ) ;
}
2018-08-19 17:05:42 +00:00
else if ( this - > m_Front )
2011-08-13 00:12:40 +00:00
{
2015-11-14 23:00:43 +00:00
CLayerFront * pGrabbed = new CLayerFront ( r . w , r . h ) ;
pGrabbed - > m_pEditor = m_pEditor ;
2012-08-12 10:41:50 +00:00
pGrabbed - > m_Texture = m_Texture ;
2015-11-14 23:00:43 +00:00
pGrabbed - > m_Image = m_Image ;
pGrabbed - > m_Game = m_Game ;
2020-09-26 19:41:58 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
2018-09-11 08:35:02 +00:00
{
pGrabbed - > m_Color = m_Color ;
pGrabbed - > m_Color . a = 255 ;
}
2018-08-09 10:07:49 +00:00
2015-11-14 23:00:43 +00:00
pBrush - > AddLayer ( pGrabbed ) ;
// copy the tiles
for ( int y = 0 ; y < r . h ; y + + )
for ( int x = 0 ; x < r . w ; x + + )
2020-09-26 19:41:58 +00:00
pGrabbed - > m_pTiles [ y * pGrabbed - > m_Width + x ] = GetTile ( r . x + x , r . y + y ) ;
2011-08-13 00:12:40 +00:00
str_copy ( pGrabbed - > m_aFileName , m_pEditor - > m_aFileName , sizeof ( pGrabbed - > m_aFileName ) ) ;
}
2010-09-30 21:31:19 +00:00
else
{
2015-11-14 23:00:43 +00:00
CLayerTiles * pGrabbed = new CLayerTiles ( r . w , r . h ) ;
pGrabbed - > m_pEditor = m_pEditor ;
2012-08-12 10:41:50 +00:00
pGrabbed - > m_Texture = m_Texture ;
2015-11-14 23:00:43 +00:00
pGrabbed - > m_Image = m_Image ;
pGrabbed - > m_Game = m_Game ;
2020-09-26 19:41:58 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
2018-09-11 08:35:02 +00:00
{
pGrabbed - > m_Color = m_Color ;
pGrabbed - > m_Color . a = 255 ;
}
2018-08-09 10:07:49 +00:00
2015-11-14 23:00:43 +00:00
pBrush - > AddLayer ( pGrabbed ) ;
// copy the tiles
for ( int y = 0 ; y < r . h ; y + + )
for ( int x = 0 ; x < r . w ; x + + )
2020-09-26 19:41:58 +00:00
pGrabbed - > m_pTiles [ y * pGrabbed - > m_Width + x ] = GetTile ( r . x + x , r . y + y ) ;
2010-12-19 14:10:42 +00:00
str_copy ( pGrabbed - > m_aFileName , m_pEditor - > m_aFileName , sizeof ( pGrabbed - > m_aFileName ) ) ;
2010-09-30 21:31:19 +00:00
}
2011-04-13 18:37:12 +00:00
2008-01-12 12:27:55 +00:00
return 1 ;
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : FillSelection ( bool Empty , CLayer * pBrush , CUIRect Rect )
2008-01-12 12:27:55 +00:00
{
2018-10-30 17:56:46 +00:00
if ( m_Readonly | | ( ! Empty & & pBrush - > m_Type ! = LAYERTYPE_TILES ) )
2018-09-26 12:53:25 +00:00
return ;
2011-04-13 18:37:12 +00:00
2012-01-12 21:03:55 +00:00
Snap ( & Rect ) ;
2010-05-29 07:25:38 +00:00
int sx = ConvertX ( Rect . x ) ;
int sy = ConvertY ( Rect . y ) ;
int w = ConvertX ( Rect . w ) ;
int h = ConvertY ( Rect . h ) ;
2011-04-13 18:37:12 +00:00
2020-09-26 19:41:58 +00:00
CLayerTiles * pLt = static_cast < CLayerTiles * > ( pBrush ) ;
2011-04-13 18:37:12 +00:00
2019-04-30 12:24:13 +00:00
bool Destructive = m_pEditor - > m_BrushDrawDestructive | | Empty | | IsEmpty ( pLt ) ;
2019-03-26 18:15:24 +00:00
2012-01-12 21:03:55 +00:00
for ( int y = 0 ; y < h ; y + + )
2010-05-29 07:25:38 +00:00
{
2012-01-12 21:03:55 +00:00
for ( int x = 0 ; x < w ; x + + )
2010-05-29 07:25:38 +00:00
{
2020-09-26 19:41:58 +00:00
int fx = x + sx ;
int fy = y + sy ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
continue ;
2011-04-13 18:37:12 +00:00
2019-04-11 19:18:48 +00:00
bool HasTile = GetTile ( fx , fy ) . m_Index ;
2019-04-30 12:24:13 +00:00
if ( ! Empty & & pLt - > GetTile ( x , y ) . m_Index = = TILE_THROUGH_CUT )
2019-04-11 19:18:48 +00:00
{
if ( m_Game & & m_pEditor - > m_Map . m_pFrontLayer )
{
HasTile = HasTile | | m_pEditor - > m_Map . m_pFrontLayer - > GetTile ( fx , fy ) . m_Index ;
}
else if ( m_Front )
{
HasTile = HasTile | | m_pEditor - > m_Map . m_pGameLayer - > GetTile ( fx , fy ) . m_Index ;
}
}
if ( ! Destructive & & HasTile )
2019-03-26 18:15:24 +00:00
continue ;
2011-04-13 18:37:12 +00:00
if ( Empty )
2020-09-26 19:41:58 +00:00
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
2011-04-13 18:37:12 +00:00
else
2020-09-26 19:41:58 +00:00
SetTile ( fx , fy , pLt - > m_pTiles [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] ) ;
2010-05-29 07:25:38 +00:00
}
}
2018-10-04 13:26:41 +00:00
FlagModified ( sx , sy , w , h ) ;
2010-05-29 07:25:38 +00:00
}
void CLayerTiles : : BrushDraw ( CLayer * pBrush , float wx , float wy )
{
if ( m_Readonly )
2008-03-20 23:59:41 +00:00
return ;
2011-04-13 18:37:12 +00:00
2008-01-12 12:27:55 +00:00
//
2010-05-29 07:25:38 +00:00
CLayerTiles * l = ( CLayerTiles * ) pBrush ;
int sx = ConvertX ( wx ) ;
int sy = ConvertY ( wy ) ;
2011-04-13 18:37:12 +00:00
2019-03-26 18:15:24 +00:00
bool Destructive = m_pEditor - > m_BrushDrawDestructive | | IsEmpty ( l ) ;
2010-05-29 07:25:38 +00:00
for ( int y = 0 ; y < l - > m_Height ; y + + )
for ( int x = 0 ; x < l - > m_Width ; x + + )
2008-01-12 12:27:55 +00:00
{
2020-09-26 19:41:58 +00:00
int fx = x + sx ;
int fy = y + sy ;
2019-03-26 18:15:24 +00:00
2020-09-26 19:41:58 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
2008-01-12 12:27:55 +00:00
continue ;
2011-04-09 06:41:31 +00:00
2019-04-11 19:18:48 +00:00
bool HasTile = GetTile ( fx , fy ) . m_Index ;
if ( l - > GetTile ( x , y ) . m_Index = = TILE_THROUGH_CUT )
{
if ( m_Game & & m_pEditor - > m_Map . m_pFrontLayer )
{
HasTile = HasTile | | m_pEditor - > m_Map . m_pFrontLayer - > GetTile ( fx , fy ) . m_Index ;
}
else if ( m_Front )
{
HasTile = HasTile | | m_pEditor - > m_Map . m_pGameLayer - > GetTile ( fx , fy ) . m_Index ;
}
}
if ( ! Destructive & & HasTile )
2019-03-26 18:15:24 +00:00
continue ;
SetTile ( fx , fy , l - > GetTile ( x , y ) ) ;
2008-01-12 12:27:55 +00:00
}
2019-03-26 18:15:24 +00:00
2019-01-10 14:39:11 +00:00
FlagModified ( sx , sy , l - > m_Width , l - > m_Height ) ;
2008-01-12 12:27:55 +00:00
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : BrushFlipX ( )
2008-01-12 12:27:55 +00:00
{
2022-06-05 20:21:24 +00:00
BrushFlipXImpl ( m_pTiles ) ;
2008-01-12 12:27:55 +00:00
2020-01-17 17:22:41 +00:00
if ( m_Tele | | m_Speedup | | m_Tune )
2019-03-21 21:50:22 +00:00
return ;
2020-01-17 17:22:41 +00:00
bool Rotate = ! ( m_Game | | m_Front | | m_Switch ) | | m_pEditor - > m_AllowPlaceUnusedTiles ;
2014-10-01 16:55:53 +00:00
for ( int y = 0 ; y < m_Height ; y + + )
for ( int x = 0 ; x < m_Width ; x + + )
2020-09-26 19:41:58 +00:00
if ( ! Rotate & & ! IsRotatableTile ( m_pTiles [ y * m_Width + x ] . m_Index ) )
m_pTiles [ y * m_Width + x ] . m_Flags = 0 ;
2019-03-21 21:50:22 +00:00
else
2020-09-26 19:41:58 +00:00
m_pTiles [ y * m_Width + x ] . m_Flags ^ = m_pTiles [ y * m_Width + x ] . m_Flags & TILEFLAG_ROTATE ? TILEFLAG_HFLIP : TILEFLAG_VFLIP ;
2008-01-12 12:27:55 +00:00
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : BrushFlipY ( )
2008-01-12 12:27:55 +00:00
{
2022-06-05 20:21:24 +00:00
BrushFlipYImpl ( m_pTiles ) ;
2008-01-12 12:27:55 +00:00
2020-01-17 17:22:41 +00:00
if ( m_Tele | | m_Speedup | | m_Tune )
2019-03-21 21:50:22 +00:00
return ;
2020-01-17 17:22:41 +00:00
bool Rotate = ! ( m_Game | | m_Front | | m_Switch ) | | m_pEditor - > m_AllowPlaceUnusedTiles ;
2014-10-01 16:55:53 +00:00
for ( int y = 0 ; y < m_Height ; y + + )
for ( int x = 0 ; x < m_Width ; x + + )
2020-09-26 19:41:58 +00:00
if ( ! Rotate & & ! IsRotatableTile ( m_pTiles [ y * m_Width + x ] . m_Index ) )
m_pTiles [ y * m_Width + x ] . m_Flags = 0 ;
2019-03-21 21:50:22 +00:00
else
2020-09-26 19:41:58 +00:00
m_pTiles [ y * m_Width + x ] . m_Flags ^ = m_pTiles [ y * m_Width + x ] . m_Flags & TILEFLAG_ROTATE ? TILEFLAG_VFLIP : TILEFLAG_HFLIP ;
2010-09-05 17:01:01 +00:00
}
void CLayerTiles : : BrushRotate ( float Amount )
{
2020-09-26 19:41:58 +00:00
int Rotation = ( round_to_int ( 360.0f * Amount / ( pi * 2 ) ) / 90 ) % 4 ; // 0=0°, 1=90°, 2=180°, 3=270°
2010-09-05 17:01:01 +00:00
if ( Rotation < 0 )
2020-09-26 19:41:58 +00:00
Rotation + = 4 ;
2010-09-05 17:01:01 +00:00
if ( Rotation = = 1 | | Rotation = = 3 )
{
2014-03-19 09:26:38 +00:00
// 90° rotation
2020-09-26 19:41:58 +00:00
CTile * pTempData = new CTile [ m_Width * m_Height ] ;
2020-10-05 17:03:14 +00:00
mem_copy ( pTempData , m_pTiles , ( size_t ) m_Width * m_Height * sizeof ( CTile ) ) ;
2010-09-05 17:01:01 +00:00
CTile * pDst = m_pTiles ;
2019-03-21 21:50:22 +00:00
bool Rotate = ! ( m_Game | | m_Front ) | | m_pEditor - > m_AllowPlaceUnusedTiles ;
2010-09-05 17:01:01 +00:00
for ( int x = 0 ; x < m_Width ; + + x )
2020-09-26 19:41:58 +00:00
for ( int y = m_Height - 1 ; y > = 0 ; - - y , + + pDst )
2010-09-05 17:01:01 +00:00
{
2020-09-26 19:41:58 +00:00
* pDst = pTempData [ y * m_Width + x ] ;
2019-03-21 21:50:22 +00:00
if ( ! Rotate & & ! IsRotatableTile ( pDst - > m_Index ) )
pDst - > m_Flags = 0 ;
else
{
2020-09-26 19:41:58 +00:00
if ( pDst - > m_Flags & TILEFLAG_ROTATE )
pDst - > m_Flags ^ = ( TILEFLAG_HFLIP | TILEFLAG_VFLIP ) ;
2019-03-21 21:50:22 +00:00
pDst - > m_Flags ^ = TILEFLAG_ROTATE ;
}
2010-09-05 17:01:01 +00:00
}
2022-05-15 18:44:05 +00:00
std : : swap ( m_Width , m_Height ) ;
2010-09-05 17:01:01 +00:00
delete [ ] pTempData ;
}
if ( Rotation = = 2 | | Rotation = = 3 )
{
BrushFlipX ( ) ;
BrushFlipY ( ) ;
}
2008-01-12 12:27:55 +00:00
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : Resize ( int NewW , int NewH )
2008-01-12 12:27:55 +00:00
{
2020-09-26 19:41:58 +00:00
CTile * pNewData = new CTile [ NewW * NewH ] ;
2020-10-05 17:03:14 +00:00
mem_zero ( pNewData , ( size_t ) NewW * NewH * sizeof ( CTile ) ) ;
2008-01-12 12:27:55 +00:00
2011-04-13 18:37:12 +00:00
// copy old data
2019-04-26 19:36:49 +00:00
for ( int y = 0 ; y < minimum ( NewH , m_Height ) ; y + + )
2020-09-26 19:41:58 +00:00
mem_copy ( & pNewData [ y * NewW ] , & m_pTiles [ y * m_Width ] , minimum ( m_Width , NewW ) * sizeof ( CTile ) ) ;
2011-04-13 18:37:12 +00:00
2008-01-12 12:27:55 +00:00
// replace old
2020-09-26 19:41:58 +00:00
delete [ ] m_pTiles ;
2010-05-29 07:25:38 +00:00
m_pTiles = pNewData ;
m_Width = NewW ;
m_Height = NewH ;
2010-09-30 21:31:19 +00:00
// resize tele layer if available
if ( m_Game & & m_pEditor - > m_Map . m_pTeleLayer & & ( m_pEditor - > m_Map . m_pTeleLayer - > m_Width ! = NewW | | m_pEditor - > m_Map . m_pTeleLayer - > m_Height ! = NewH ) )
m_pEditor - > m_Map . m_pTeleLayer - > Resize ( NewW , NewH ) ;
// resize speedup layer if available
if ( m_Game & & m_pEditor - > m_Map . m_pSpeedupLayer & & ( m_pEditor - > m_Map . m_pSpeedupLayer - > m_Width ! = NewW | | m_pEditor - > m_Map . m_pSpeedupLayer - > m_Height ! = NewH ) )
m_pEditor - > m_Map . m_pSpeedupLayer - > Resize ( NewW , NewH ) ;
// resize front layer
if ( m_Game & & m_pEditor - > m_Map . m_pFrontLayer & & ( m_pEditor - > m_Map . m_pFrontLayer - > m_Width ! = NewW | | m_pEditor - > m_Map . m_pFrontLayer - > m_Height ! = NewH ) )
m_pEditor - > m_Map . m_pFrontLayer - > Resize ( NewW , NewH ) ;
// resize switch layer if available
if ( m_Game & & m_pEditor - > m_Map . m_pSwitchLayer & & ( m_pEditor - > m_Map . m_pSwitchLayer - > m_Width ! = NewW | | m_pEditor - > m_Map . m_pSwitchLayer - > m_Height ! = NewH ) )
m_pEditor - > m_Map . m_pSwitchLayer - > Resize ( NewW , NewH ) ;
2015-07-09 00:08:14 +00:00
2014-03-12 22:34:30 +00:00
// resize tune layer if available
if ( m_Game & & m_pEditor - > m_Map . m_pTuneLayer & & ( m_pEditor - > m_Map . m_pTuneLayer - > m_Width ! = NewW | | m_pEditor - > m_Map . m_pTuneLayer - > m_Height ! = NewH ) )
2019-03-12 01:35:29 +00:00
m_pEditor - > m_Map . m_pTuneLayer - > Resize ( NewW , NewH ) ;
2008-01-12 12:27:55 +00:00
}
2010-10-09 16:38:23 +00:00
void CLayerTiles : : Shift ( int Direction )
{
2022-06-05 20:03:16 +00:00
ShiftImpl ( m_pTiles , Direction , m_pEditor - > m_ShiftBy ) ;
2010-10-09 16:38:23 +00:00
}
2008-01-12 12:27:55 +00:00
2011-02-18 10:41:27 +00:00
void CLayerTiles : : ShowInfo ( )
{
float ScreenX0 , ScreenY0 , ScreenX1 , ScreenY1 ;
Graphics ( ) - > GetScreen ( & ScreenX0 , & ScreenY0 , & ScreenX1 , & ScreenY1 ) ;
Graphics ( ) - > TextureSet ( m_pEditor - > Client ( ) - > GetDebugFont ( ) ) ;
2012-10-14 12:04:48 +00:00
Graphics ( ) - > QuadsBegin ( ) ;
2011-04-13 18:37:12 +00:00
2020-09-26 19:41:58 +00:00
int StartY = maximum ( 0 , ( int ) ( ScreenY0 / 32.0f ) - 1 ) ;
int StartX = maximum ( 0 , ( int ) ( ScreenX0 / 32.0f ) - 1 ) ;
int EndY = minimum ( ( int ) ( ScreenY1 / 32.0f ) + 1 , m_Height ) ;
int EndX = minimum ( ( int ) ( ScreenX1 / 32.0f ) + 1 , m_Width ) ;
2011-04-13 18:37:12 +00:00
2011-02-18 10:41:27 +00:00
for ( int y = StartY ; y < EndY ; y + + )
for ( int x = StartX ; x < EndX ; x + + )
{
2020-09-26 19:41:58 +00:00
int c = x + y * m_Width ;
2011-02-18 10:41:27 +00:00
if ( m_pTiles [ c ] . m_Index )
{
char aBuf [ 64 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " %i " , m_pTiles [ c ] . m_Index ) ;
2020-09-26 19:41:58 +00:00
m_pEditor - > Graphics ( ) - > QuadsText ( x * 32 , y * 32 , 16.0f , aBuf ) ;
2011-02-18 10:41:27 +00:00
2020-09-26 19:41:58 +00:00
char aFlags [ 4 ] = { m_pTiles [ c ] . m_Flags & TILEFLAG_VFLIP ? ' V ' : ' ' ,
m_pTiles [ c ] . m_Flags & TILEFLAG_HFLIP ? ' H ' : ' ' ,
m_pTiles [ c ] . m_Flags & TILEFLAG_ROTATE ? ' R ' : ' ' ,
0 } ;
m_pEditor - > Graphics ( ) - > QuadsText ( x * 32 , y * 32 + 16 , 16.0f , aFlags ) ;
2011-02-18 10:41:27 +00:00
}
x + = m_pTiles [ c ] . m_Skip ;
}
2011-06-02 17:16:22 +00:00
2012-10-14 12:04:48 +00:00
Graphics ( ) - > QuadsEnd ( ) ;
2011-06-02 17:16:22 +00:00
Graphics ( ) - > MapScreen ( ScreenX0 , ScreenY0 , ScreenX1 , ScreenY1 ) ;
2011-02-18 10:41:27 +00:00
}
2010-05-29 07:25:38 +00:00
int CLayerTiles : : RenderProperties ( CUIRect * pToolBox )
2008-01-12 12:27:55 +00:00
{
2010-05-29 07:25:38 +00:00
CUIRect Button ;
2011-08-11 08:59:14 +00:00
2020-09-26 19:41:58 +00:00
bool IsGameLayer = ( m_pEditor - > m_Map . m_pGameLayer = = this | | m_pEditor - > m_Map . m_pTeleLayer = = this | | m_pEditor - > m_Map . m_pSpeedupLayer = = this | | m_pEditor - > m_Map . m_pFrontLayer = = this | | m_pEditor - > m_Map . m_pSwitchLayer = = this | | m_pEditor - > m_Map . m_pTuneLayer = = this ) ;
2010-12-15 11:49:36 +00:00
2022-06-11 19:38:18 +00:00
CLayerGroup * pGroup = m_pEditor - > m_Map . m_vpGroups [ m_pEditor - > m_SelectedGroup ] ;
2019-03-12 01:35:29 +00:00
// Game tiles can only be constructed if the layer is relative to the game layer
if ( ! IsGameLayer & & ! ( pGroup - > m_OffsetX % 32 ) & & ! ( pGroup - > m_OffsetY % 32 ) & & pGroup - > m_ParallaxX = = 100 & & pGroup - > m_ParallaxY = = 100 )
2008-09-07 08:30:49 +00:00
{
2011-07-08 23:09:06 +00:00
pToolBox - > HSplitBottom ( 12.0f , pToolBox , & Button ) ;
2010-12-15 11:49:36 +00:00
static int s_ColclButton = 0 ;
2011-03-20 16:04:03 +00:00
if ( m_pEditor - > DoButton_Editor ( & s_ColclButton , " Game tiles " , 0 , & Button , 0 , " Constructs game tiles from this layer " ) )
2011-02-12 18:10:45 +00:00
m_pEditor - > PopupSelectGametileOpInvoke ( m_pEditor - > UI ( ) - > MouseX ( ) , m_pEditor - > UI ( ) - > MouseY ( ) ) ;
int Result = m_pEditor - > PopupSelectGameTileOpResult ( ) ;
2011-02-13 05:35:13 +00:00
switch ( Result )
2016-05-04 21:37:02 +00:00
{
2020-09-26 19:41:58 +00:00
case 4 :
Result = TILE_THROUGH_CUT ;
break ;
case 5 :
Result = TILE_FREEZE ;
break ;
case 6 :
Result = TILE_UNFREEZE ;
break ;
case 7 :
Result = TILE_DFREEZE ;
break ;
case 8 :
Result = TILE_DUNFREEZE ;
break ;
case 9 :
Result = TILE_TELECHECKIN ;
break ;
case 10 :
Result = TILE_TELECHECKINEVIL ;
2022-01-07 15:53:40 +00:00
break ;
case 11 :
Result = TILE_LFREEZE ;
break ;
case 12 :
Result = TILE_LUNFREEZE ;
break ;
2020-09-26 19:41:58 +00:00
default :
break ;
2010-12-15 11:49:36 +00:00
}
2011-02-12 18:10:45 +00:00
if ( Result > - 1 )
2010-12-15 11:49:36 +00:00
{
2019-03-12 01:35:29 +00:00
int OffsetX = - pGroup - > m_OffsetX / 32 ;
int OffsetY = - pGroup - > m_OffsetY / 32 ;
if ( Result ! = TILE_TELECHECKIN & & Result ! = TILE_TELECHECKINEVIL )
2014-02-12 20:44:05 +00:00
{
2019-03-12 01:35:29 +00:00
CLayerTiles * pGLayer = m_pEditor - > m_Map . m_pGameLayer ;
if ( pGLayer - > m_Width < m_Width + OffsetX | | pGLayer - > m_Height < m_Height + OffsetY )
{
int NewW = pGLayer - > m_Width < m_Width + OffsetX ? m_Width + OffsetX : pGLayer - > m_Width ;
int NewH = pGLayer - > m_Height < m_Height + OffsetY ? m_Height + OffsetY : pGLayer - > m_Height ;
pGLayer - > Resize ( NewW , NewH ) ;
}
for ( int y = OffsetY < 0 ? - OffsetY : 0 ; y < m_Height ; y + + )
for ( int x = OffsetX < 0 ? - OffsetX : 0 ; x < m_Width ; x + + )
if ( GetTile ( x , y ) . m_Index )
{
CTile ResultTile = { ( unsigned char ) Result } ;
pGLayer - > SetTile ( x + OffsetX , y + OffsetY , ResultTile ) ;
2016-05-01 15:44:02 +00:00
}
2014-02-12 20:44:05 +00:00
}
2019-03-12 01:35:29 +00:00
else
2014-02-12 20:44:05 +00:00
{
2019-03-12 01:35:29 +00:00
if ( ! m_pEditor - > m_Map . m_pTeleLayer )
{
CLayer * pLayer = new CLayerTele ( m_Width , m_Height ) ;
m_pEditor - > m_Map . MakeTeleLayer ( pLayer ) ;
m_pEditor - > m_Map . m_pGameGroup - > AddLayer ( pLayer ) ;
}
2014-02-12 20:44:05 +00:00
2019-03-12 01:35:29 +00:00
CLayerTele * pTLayer = m_pEditor - > m_Map . m_pTeleLayer ;
if ( pTLayer - > m_Width < m_Width + OffsetX | | pTLayer - > m_Height < m_Height + OffsetY )
{
int NewW = pTLayer - > m_Width < m_Width + OffsetX ? m_Width + OffsetX : pTLayer - > m_Width ;
int NewH = pTLayer - > m_Height < m_Height + OffsetY ? m_Height + OffsetY : pTLayer - > m_Height ;
pTLayer - > Resize ( NewW , NewH ) ;
}
for ( int y = OffsetY < 0 ? - OffsetY : 0 ; y < m_Height ; y + + )
for ( int x = OffsetX < 0 ? - OffsetX : 0 ; x < m_Width ; x + + )
if ( GetTile ( x , y ) . m_Index )
2014-02-12 20:44:05 +00:00
{
2020-09-26 19:41:58 +00:00
pTLayer - > m_pTiles [ ( y + OffsetY ) * pTLayer - > m_Width + x + OffsetX ] . m_Index = TILE_AIR + Result ;
pTLayer - > m_pTeleTile [ ( y + OffsetY ) * pTLayer - > m_Width + x + OffsetX ] . m_Number = 1 ;
pTLayer - > m_pTeleTile [ ( y + OffsetY ) * pTLayer - > m_Width + x + OffsetX ] . m_Type = TILE_AIR + Result ;
2014-02-12 20:44:05 +00:00
}
}
2011-02-12 18:10:45 +00:00
2010-12-15 11:49:36 +00:00
return 1 ;
}
2008-01-13 22:03:32 +00:00
}
2019-03-12 01:35:29 +00:00
2018-10-03 16:16:58 +00:00
if ( m_pEditor - > m_Map . m_pGameLayer ! = this )
{
2022-06-11 19:38:18 +00:00
if ( m_Image > = 0 & & ( size_t ) m_Image < m_pEditor - > m_Map . m_vpImages . size ( ) & & m_pEditor - > m_Map . m_vpImages [ m_Image ] - > m_AutoMapper . IsLoaded ( ) & &
2018-10-03 16:16:58 +00:00
m_AutoMapperConfig ! = - 1 )
{
static int s_AutoMapperButton = 0 ;
static int s_AutoMapperButtonAuto = 0 ;
2022-06-13 16:28:13 +00:00
pToolBox - > HSplitBottom ( 2.0f , pToolBox , nullptr ) ;
2018-10-03 16:16:58 +00:00
pToolBox - > HSplitBottom ( 12.0f , pToolBox , & Button ) ;
2020-09-26 19:41:58 +00:00
if ( m_Seed ! = 0 )
{
2018-10-03 16:16:58 +00:00
CUIRect ButtonAuto ;
Button . VSplitRight ( 16.0f , & Button , & ButtonAuto ) ;
2022-06-13 16:28:13 +00:00
Button . VSplitRight ( 2.0f , & Button , nullptr ) ;
2018-10-03 16:16:58 +00:00
if ( m_pEditor - > DoButton_Editor ( & s_AutoMapperButtonAuto , " A " , m_AutoAutoMap , & ButtonAuto , 0 , " Automatically run automap after modifications. " ) )
{
m_AutoAutoMap = ! m_AutoAutoMap ;
2018-10-04 13:26:41 +00:00
FlagModified ( 0 , 0 , m_Width , m_Height ) ;
2018-10-03 16:16:58 +00:00
}
}
if ( m_pEditor - > DoButton_Editor ( & s_AutoMapperButton , " Automap " , 0 , & Button , 0 , " Run the automapper " ) )
{
2022-06-11 19:38:18 +00:00
m_pEditor - > m_Map . m_vpImages [ m_Image ] - > m_AutoMapper . Proceed ( this , m_AutoMapperConfig , m_Seed ) ;
2018-10-03 16:16:58 +00:00
return 1 ;
}
}
}
2011-04-13 18:37:12 +00:00
2008-01-12 12:27:55 +00:00
enum
{
2020-09-26 19:41:58 +00:00
PROP_WIDTH = 0 ,
2008-01-12 12:27:55 +00:00
PROP_HEIGHT ,
2010-10-09 16:38:23 +00:00
PROP_SHIFT ,
2014-05-31 23:32:54 +00:00
PROP_SHIFT_BY ,
2008-03-21 00:13:55 +00:00
PROP_IMAGE ,
2011-01-04 10:38:14 +00:00
PROP_COLOR ,
2011-07-18 10:05:12 +00:00
PROP_COLOR_ENV ,
PROP_COLOR_ENV_OFFSET ,
2018-10-03 16:16:58 +00:00
PROP_AUTOMAPPER ,
PROP_SEED ,
2008-01-12 12:27:55 +00:00
NUM_PROPS ,
} ;
2011-04-13 18:37:12 +00:00
2011-01-04 10:38:14 +00:00
int Color = 0 ;
2020-09-26 19:41:58 +00:00
Color | = m_Color . r < < 24 ;
Color | = m_Color . g < < 16 ;
Color | = m_Color . b < < 8 ;
2011-01-04 10:38:14 +00:00
Color | = m_Color . a ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
CProperty aProps [ ] = {
2019-04-17 19:48:23 +00:00
{ " Width " , m_Width , PROPTYPE_INT_SCROLL , 1 , 100000 } ,
{ " Height " , m_Height , PROPTYPE_INT_SCROLL , 1 , 100000 } ,
2011-03-20 16:04:03 +00:00
{ " Shift " , 0 , PROPTYPE_SHIFT , 0 , 0 } ,
2019-04-17 19:48:23 +00:00
{ " Shift by " , m_pEditor - > m_ShiftBy , PROPTYPE_INT_SCROLL , 1 , 100000 } ,
2020-05-30 07:08:59 +00:00
{ " Image " , m_Image , PROPTYPE_IMAGE , 0 , 0 } ,
2011-03-20 16:04:03 +00:00
{ " Color " , Color , PROPTYPE_COLOR , 0 , 0 } ,
2020-09-26 19:41:58 +00:00
{ " Color Env " , m_ColorEnv + 1 , PROPTYPE_ENVELOPE , 0 , 0 } ,
2011-07-18 10:05:12 +00:00
{ " Color TO " , m_ColorEnvOffset , PROPTYPE_INT_SCROLL , - 1000000 , 1000000 } ,
2018-10-03 16:16:58 +00:00
{ " Auto Rule " , m_AutoMapperConfig , PROPTYPE_AUTOMAPPER , m_Image , 0 } ,
{ " Seed " , m_Seed , PROPTYPE_INT_SCROLL , 0 , 1000000000 } ,
2022-06-13 16:28:13 +00:00
{ nullptr } ,
2008-01-12 12:27:55 +00:00
} ;
2011-04-09 06:41:31 +00:00
2019-03-12 01:35:29 +00:00
if ( IsGameLayer ) // remove the image and color properties if this is a game layer
2011-01-04 10:38:14 +00:00
{
2022-06-13 16:28:13 +00:00
aProps [ PROP_IMAGE ] . m_pName = nullptr ;
aProps [ PROP_COLOR ] . m_pName = nullptr ;
aProps [ PROP_AUTOMAPPER ] . m_pName = nullptr ;
2018-10-03 16:16:58 +00:00
}
if ( m_Image = = - 1 )
{
2022-06-13 16:28:13 +00:00
aProps [ PROP_AUTOMAPPER ] . m_pName = nullptr ;
aProps [ PROP_SEED ] . m_pName = nullptr ;
2011-01-04 10:38:14 +00:00
}
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
static int s_aIds [ NUM_PROPS ] = { 0 } ;
int NewVal = 0 ;
2011-03-21 23:31:42 +00:00
int Prop = m_pEditor - > DoProperties ( pToolBox , aProps , s_aIds , & NewVal ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
if ( Prop = = PROP_WIDTH & & NewVal > 1 )
2016-04-27 15:49:14 +00:00
{
if ( NewVal > 1000 & & ! m_pEditor - > m_LargeLayerWasWarned )
{
m_pEditor - > m_PopupEventType = m_pEditor - > POPEVENT_LARGELAYER ;
m_pEditor - > m_PopupEventActivated = true ;
m_pEditor - > m_LargeLayerWasWarned = true ;
}
2010-05-29 07:25:38 +00:00
Resize ( NewVal , m_Height ) ;
2016-04-27 15:49:14 +00:00
}
2010-05-29 07:25:38 +00:00
else if ( Prop = = PROP_HEIGHT & & NewVal > 1 )
2016-04-27 15:49:14 +00:00
{
if ( NewVal > 1000 & & ! m_pEditor - > m_LargeLayerWasWarned )
{
m_pEditor - > m_PopupEventType = m_pEditor - > POPEVENT_LARGELAYER ;
m_pEditor - > m_PopupEventActivated = true ;
m_pEditor - > m_LargeLayerWasWarned = true ;
}
2010-05-29 07:25:38 +00:00
Resize ( m_Width , NewVal ) ;
2016-04-27 15:49:14 +00:00
}
2010-10-09 16:38:23 +00:00
else if ( Prop = = PROP_SHIFT )
Shift ( NewVal ) ;
2014-05-31 23:32:54 +00:00
else if ( Prop = = PROP_SHIFT_BY )
m_pEditor - > m_ShiftBy = NewVal ;
2010-05-29 07:25:38 +00:00
else if ( Prop = = PROP_IMAGE )
2008-09-07 08:30:49 +00:00
{
2020-05-28 08:09:27 +00:00
m_Image = NewVal ;
2020-09-26 19:41:58 +00:00
if ( NewVal = = - 1 )
2008-09-07 08:30:49 +00:00
{
2016-07-02 08:33:37 +00:00
m_Texture . Invalidate ( ) ;
2020-05-30 07:08:59 +00:00
m_Image = - 1 ;
2008-09-07 08:30:49 +00:00
}
else
2018-10-03 16:16:58 +00:00
{
2022-06-11 19:38:18 +00:00
m_Image = NewVal % m_pEditor - > m_Map . m_vpImages . size ( ) ;
2018-10-03 16:16:58 +00:00
m_AutoMapperConfig = - 1 ;
2020-06-20 23:14:36 +00:00
2022-06-11 19:38:18 +00:00
if ( m_pEditor - > m_Map . m_vpImages [ m_Image ] - > m_Width % 16 ! = 0 | | m_pEditor - > m_Map . m_vpImages [ m_Image ] - > m_Height % 16 ! = 0 )
2020-06-20 23:14:36 +00:00
{
m_pEditor - > m_PopupEventType = m_pEditor - > POPEVENT_IMAGEDIV16 ;
m_pEditor - > m_PopupEventActivated = true ;
2020-09-21 03:57:54 +00:00
m_Texture = IGraphics : : CTextureHandle ( ) ;
m_Image = - 1 ;
2020-06-20 23:14:36 +00:00
}
2018-10-03 16:16:58 +00:00
}
2008-09-07 08:30:49 +00:00
}
2011-01-04 10:38:14 +00:00
else if ( Prop = = PROP_COLOR )
{
2020-09-26 19:41:58 +00:00
m_Color . r = ( NewVal > > 24 ) & 0xff ;
m_Color . g = ( NewVal > > 16 ) & 0xff ;
m_Color . b = ( NewVal > > 8 ) & 0xff ;
m_Color . a = NewVal & 0xff ;
2011-01-04 10:38:14 +00:00
}
2011-07-18 10:05:12 +00:00
if ( Prop = = PROP_COLOR_ENV )
2011-08-06 20:30:18 +00:00
{
2022-06-11 19:38:18 +00:00
int Index = clamp ( NewVal - 1 , - 1 , ( int ) m_pEditor - > m_Map . m_vpEnvelopes . size ( ) - 1 ) ;
2020-09-26 19:41:58 +00:00
int Step = ( Index - m_ColorEnv ) % 2 ;
2011-08-06 20:30:18 +00:00
if ( Step ! = 0 )
{
2022-06-11 19:38:18 +00:00
for ( ; Index > = - 1 & & Index < ( int ) m_pEditor - > m_Map . m_vpEnvelopes . size ( ) ; Index + = Step )
if ( Index = = - 1 | | m_pEditor - > m_Map . m_vpEnvelopes [ Index ] - > m_Channels = = 4 )
2011-08-06 20:30:18 +00:00
{
m_ColorEnv = Index ;
break ;
}
}
}
2011-07-18 10:05:12 +00:00
if ( Prop = = PROP_COLOR_ENV_OFFSET )
m_ColorEnvOffset = NewVal ;
2018-10-03 16:16:58 +00:00
else if ( Prop = = PROP_SEED )
m_Seed = NewVal ;
else if ( Prop = = PROP_AUTOMAPPER )
{
2022-06-11 19:38:18 +00:00
if ( m_Image > = 0 & & m_pEditor - > m_Map . m_vpImages [ m_Image ] - > m_AutoMapper . ConfigNamesNum ( ) > 0 & & NewVal > = 0 )
m_AutoMapperConfig = NewVal % m_pEditor - > m_Map . m_vpImages [ m_Image ] - > m_AutoMapper . ConfigNamesNum ( ) ;
2018-10-03 16:16:58 +00:00
else
m_AutoMapperConfig = - 1 ;
}
2020-09-26 19:41:58 +00:00
if ( Prop ! = - 1 )
{
2018-10-04 13:26:41 +00:00
FlagModified ( 0 , 0 , m_Width , m_Height ) ;
2018-10-03 16:16:58 +00:00
}
2011-04-13 18:37:12 +00:00
2008-01-13 22:03:32 +00:00
return 0 ;
2008-01-12 12:27:55 +00:00
}
2008-01-19 12:32:08 +00:00
2022-06-11 19:38:18 +00:00
int CLayerTiles : : RenderCommonProperties ( SCommonPropState & State , CEditor * pEditor , CUIRect * pToolbox , std : : vector < CLayerTiles * > & vpLayers )
2020-02-27 13:53:12 +00:00
{
2020-02-28 15:25:27 +00:00
if ( State . Modified )
{
CUIRect Commit ;
pToolbox - > HSplitBottom ( 20.0f , pToolbox , & Commit ) ;
static int s_CommitButton = 0 ;
if ( pEditor - > DoButton_Editor ( & s_CommitButton , " Commit " , 0 , & Commit , 0 , " Applies the changes " ) )
{
dbg_msg ( " editor " , " applying changes " ) ;
2022-06-11 19:38:18 +00:00
for ( auto & pLayer : vpLayers )
2022-05-24 09:24:33 +00:00
{
2020-02-28 15:25:27 +00:00
pLayer - > Resize ( State . Width , State . Height ) ;
2020-09-26 19:41:58 +00:00
pLayer - > m_Color . r = ( State . Color > > 24 ) & 0xff ;
pLayer - > m_Color . g = ( State . Color > > 16 ) & 0xff ;
pLayer - > m_Color . b = ( State . Color > > 8 ) & 0xff ;
pLayer - > m_Color . a = State . Color & 0xff ;
2020-02-28 15:25:27 +00:00
pLayer - > FlagModified ( 0 , 0 , pLayer - > m_Width , pLayer - > m_Height ) ;
2022-05-24 09:24:33 +00:00
}
2020-02-28 15:25:27 +00:00
State . Modified = false ;
}
}
else
{
2022-06-11 19:38:18 +00:00
for ( auto & pLayer : vpLayers )
2022-05-24 09:24:33 +00:00
{
2020-02-28 15:25:27 +00:00
if ( pLayer - > m_Width > State . Width )
State . Width = pLayer - > m_Width ;
if ( pLayer - > m_Height > State . Height )
State . Height = pLayer - > m_Height ;
2022-05-24 09:24:33 +00:00
}
2020-02-28 15:25:27 +00:00
}
2020-02-27 15:02:36 +00:00
{
CUIRect Warning ;
pToolbox - > HSplitTop ( 13.0f , & Warning , pToolbox ) ;
Warning . HMargin ( 0.5f , & Warning ) ;
pEditor - > TextRender ( ) - > TextColor ( ColorRGBA ( 1.0f , 0.0f , 0.0f , 1.0f ) ) ;
2022-03-11 16:34:48 +00:00
SLabelProperties Props ;
Props . m_MaxWidth = Warning . w ;
pEditor - > UI ( ) - > DoLabel ( & Warning , " Editing multiple layers " , 9.0f , TEXTALIGN_LEFT , Props ) ;
2020-02-27 15:02:36 +00:00
pEditor - > TextRender ( ) - > TextColor ( ColorRGBA ( 1.0f , 1.0f , 1.0f , 1.0f ) ) ;
2022-06-13 16:28:13 +00:00
pToolbox - > HSplitTop ( 2.0f , nullptr , pToolbox ) ;
2020-02-27 15:02:36 +00:00
}
2020-02-27 13:53:12 +00:00
enum
{
2020-09-26 19:41:58 +00:00
PROP_WIDTH = 0 ,
2020-02-27 13:53:12 +00:00
PROP_HEIGHT ,
PROP_SHIFT ,
2020-02-28 12:33:32 +00:00
PROP_SHIFT_BY ,
2020-02-27 15:02:36 +00:00
PROP_COLOR ,
2020-02-27 13:53:12 +00:00
NUM_PROPS ,
} ;
CProperty aProps [ ] = {
2020-02-28 15:25:27 +00:00
{ " Width " , State . Width , PROPTYPE_INT_SCROLL , 1 , 100000 } ,
{ " Height " , State . Height , PROPTYPE_INT_SCROLL , 1 , 100000 } ,
2020-02-27 13:53:12 +00:00
{ " Shift " , 0 , PROPTYPE_SHIFT , 0 , 0 } ,
2020-02-28 12:33:32 +00:00
{ " Shift by " , pEditor - > m_ShiftBy , PROPTYPE_INT_SCROLL , 1 , 100000 } ,
2020-02-28 15:25:27 +00:00
{ " Color " , State . Color , PROPTYPE_COLOR , 0 , 0 } ,
2022-06-13 16:28:13 +00:00
{ nullptr } ,
2020-02-27 13:53:12 +00:00
} ;
static int s_aIds [ NUM_PROPS ] = { 0 } ;
int NewVal = 0 ;
int Prop = pEditor - > DoProperties ( pToolbox , aProps , s_aIds , & NewVal ) ;
if ( Prop = = PROP_WIDTH & & NewVal > 1 )
{
if ( NewVal > 1000 & & ! pEditor - > m_LargeLayerWasWarned )
{
pEditor - > m_PopupEventType = pEditor - > POPEVENT_LARGELAYER ;
pEditor - > m_PopupEventActivated = true ;
pEditor - > m_LargeLayerWasWarned = true ;
}
2020-02-28 15:25:27 +00:00
State . Width = NewVal ;
2020-02-27 13:53:12 +00:00
}
else if ( Prop = = PROP_HEIGHT & & NewVal > 1 )
{
if ( NewVal > 1000 & & ! pEditor - > m_LargeLayerWasWarned )
{
pEditor - > m_PopupEventType = pEditor - > POPEVENT_LARGELAYER ;
pEditor - > m_PopupEventActivated = true ;
pEditor - > m_LargeLayerWasWarned = true ;
}
2020-02-28 15:25:27 +00:00
State . Height = NewVal ;
2020-02-27 13:53:12 +00:00
}
else if ( Prop = = PROP_SHIFT )
{
2022-06-11 19:38:18 +00:00
for ( auto & pLayer : vpLayers )
2020-02-27 13:53:12 +00:00
pLayer - > Shift ( NewVal ) ;
}
2020-02-28 12:33:32 +00:00
else if ( Prop = = PROP_SHIFT_BY )
pEditor - > m_ShiftBy = NewVal ;
2020-02-27 15:02:36 +00:00
else if ( Prop = = PROP_COLOR )
{
2020-02-28 15:25:27 +00:00
State . Color = NewVal ;
2020-02-27 15:02:36 +00:00
}
2020-02-27 13:53:12 +00:00
2020-02-28 15:25:27 +00:00
if ( Prop ! = - 1 & & Prop ! = PROP_SHIFT )
2020-02-27 13:53:12 +00:00
{
2020-02-28 15:25:27 +00:00
State . Modified = true ;
2020-02-27 13:53:12 +00:00
}
return 0 ;
}
2019-12-21 13:35:09 +00:00
void CLayerTiles : : FlagModified ( int x , int y , int w , int h )
{
2018-10-04 13:26:41 +00:00
m_pEditor - > m_Map . m_Modified = true ;
2021-02-19 14:43:39 +00:00
if ( m_Seed ! = 0 & & m_AutoMapperConfig ! = - 1 & & m_AutoAutoMap & & m_Image > = 0 )
2020-09-26 19:41:58 +00:00
{
2022-06-11 19:38:18 +00:00
m_pEditor - > m_Map . m_vpImages [ m_Image ] - > m_AutoMapper . ProceedLocalized ( this , m_AutoMapperConfig , m_Seed , x , y , w , h ) ;
2018-10-03 16:16:58 +00:00
}
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : ModifyImageIndex ( INDEX_MODIFY_FUNC Func )
2008-01-19 12:32:08 +00:00
{
2010-05-29 07:25:38 +00:00
Func ( & m_Image ) ;
2008-01-19 12:32:08 +00:00
}
2010-05-29 07:25:38 +00:00
void CLayerTiles : : ModifyEnvelopeIndex ( INDEX_MODIFY_FUNC Func )
2008-01-19 12:32:08 +00:00
{
2020-01-23 17:30:55 +00:00
Func ( & m_ColorEnv ) ;
2008-01-19 12:32:08 +00:00
}
2010-09-30 21:31:19 +00:00
2020-09-26 19:41:58 +00:00
CLayerTele : : CLayerTele ( int w , int h ) :
CLayerTiles ( w , h )
2010-09-30 21:31:19 +00:00
{
2011-08-26 16:46:27 +00:00
//m_Type = LAYERTYPE_TELE;
2011-08-13 00:12:40 +00:00
str_copy ( m_aName , " Tele " , sizeof ( m_aName ) ) ;
2010-09-30 21:31:19 +00:00
m_Tele = 1 ;
2011-04-09 06:41:31 +00:00
2020-09-26 19:41:58 +00:00
m_pTeleTile = new CTeleTile [ w * h ] ;
2020-10-05 17:03:14 +00:00
mem_zero ( m_pTeleTile , ( size_t ) w * h * sizeof ( CTeleTile ) ) ;
2010-09-30 21:31:19 +00:00
}
CLayerTele : : ~ CLayerTele ( )
{
delete [ ] m_pTeleTile ;
}
void CLayerTele : : Resize ( int NewW , int NewH )
{
// resize tele data
2020-09-26 19:41:58 +00:00
CTeleTile * pNewTeleData = new CTeleTile [ NewW * NewH ] ;
2020-10-05 17:03:14 +00:00
mem_zero ( pNewTeleData , ( size_t ) NewW * NewH * sizeof ( CTeleTile ) ) ;
2010-09-30 21:31:19 +00:00
2011-04-09 06:41:31 +00:00
// copy old data
2019-04-26 19:36:49 +00:00
for ( int y = 0 ; y < minimum ( NewH , m_Height ) ; y + + )
2020-09-26 19:41:58 +00:00
mem_copy ( & pNewTeleData [ y * NewW ] , & m_pTeleTile [ y * m_Width ] , minimum ( m_Width , NewW ) * sizeof ( CTeleTile ) ) ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
// replace old
2020-09-26 19:41:58 +00:00
delete [ ] m_pTeleTile ;
2010-09-30 21:31:19 +00:00
m_pTeleTile = pNewTeleData ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
// resize tile data
CLayerTiles : : Resize ( NewW , NewH ) ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
// resize gamelayer too
if ( m_pEditor - > m_Map . m_pGameLayer - > m_Width ! = NewW | | m_pEditor - > m_Map . m_pGameLayer - > m_Height ! = NewH )
m_pEditor - > m_Map . m_pGameLayer - > Resize ( NewW , NewH ) ;
}
2010-10-20 13:56:29 +00:00
void CLayerTele : : Shift ( int Direction )
{
CLayerTiles : : Shift ( Direction ) ;
2022-06-05 20:03:16 +00:00
ShiftImpl ( m_pTeleTile , Direction , m_pEditor - > m_ShiftBy ) ;
2010-10-20 13:56:29 +00:00
}
2019-03-26 18:15:24 +00:00
bool CLayerTele : : IsEmpty ( CLayerTiles * pLayer )
{
for ( int y = 0 ; y < pLayer - > m_Height ; y + + )
for ( int x = 0 ; x < pLayer - > m_Width ; x + + )
2021-09-01 09:43:32 +00:00
if ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidTeleTile ( pLayer - > GetTile ( x , y ) . m_Index ) )
2019-03-26 18:15:24 +00:00
return false ;
return true ;
}
2010-09-30 21:31:19 +00:00
void CLayerTele : : BrushDraw ( CLayer * pBrush , float wx , float wy )
{
2011-08-26 16:46:27 +00:00
if ( m_Readonly )
return ;
2010-09-30 21:31:19 +00:00
CLayerTele * l = ( CLayerTele * ) pBrush ;
int sx = ConvertX ( wx ) ;
int sy = ConvertY ( wy ) ;
2010-12-19 14:10:42 +00:00
if ( str_comp ( l - > m_aFileName , m_pEditor - > m_aFileName ) )
m_pEditor - > m_TeleNumber = l - > m_TeleNum ;
2019-03-26 18:15:24 +00:00
bool Destructive = m_pEditor - > m_BrushDrawDestructive | | IsEmpty ( l ) ;
2010-09-30 21:31:19 +00:00
for ( int y = 0 ; y < l - > m_Height ; y + + )
for ( int x = 0 ; x < l - > m_Width ; x + + )
{
2020-09-26 19:41:58 +00:00
int fx = x + sx ;
int fy = y + sy ;
2019-03-26 18:15:24 +00:00
2020-09-26 19:41:58 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
2010-09-30 21:31:19 +00:00
continue ;
2011-04-09 06:41:31 +00:00
2019-03-26 18:15:24 +00:00
if ( ! Destructive & & GetTile ( fx , fy ) . m_Index )
continue ;
2021-09-01 09:43:32 +00:00
if ( ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidTeleTile ( l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ) ) & & l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ! = TILE_AIR )
2010-09-30 21:31:19 +00:00
{
2010-12-07 15:51:59 +00:00
if ( m_pEditor - > m_TeleNumber ! = l - > m_TeleNum )
2010-12-04 11:54:53 +00:00
{
2020-09-26 19:41:58 +00:00
m_pTeleTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_TeleNumber ;
2010-12-04 11:54:53 +00:00
}
2020-09-26 19:41:58 +00:00
else if ( l - > m_pTeleTile [ y * l - > m_Width + x ] . m_Number )
m_pTeleTile [ fy * m_Width + fx ] . m_Number = l - > m_pTeleTile [ y * l - > m_Width + x ] . m_Number ;
2010-12-04 11:54:53 +00:00
else
2010-09-30 21:31:19 +00:00
{
2010-12-07 15:51:59 +00:00
if ( ! m_pEditor - > m_TeleNumber )
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
m_pTeleTile [ fy * m_Width + fx ] . m_Number = 0 ;
m_pTeleTile [ fy * m_Width + fx ] . m_Type = 0 ;
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
2010-09-30 21:31:19 +00:00
continue ;
}
else
2020-09-26 19:41:58 +00:00
m_pTeleTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_TeleNumber ;
2010-09-30 21:31:19 +00:00
}
2011-04-09 06:41:31 +00:00
2020-09-26 19:41:58 +00:00
m_pTeleTile [ fy * m_Width + fx ] . m_Type = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
m_pTiles [ fy * m_Width + fx ] . m_Index = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
2010-09-30 21:31:19 +00:00
}
else
{
2020-09-26 19:41:58 +00:00
m_pTeleTile [ fy * m_Width + fx ] . m_Number = 0 ;
m_pTeleTile [ fy * m_Width + fx ] . m_Type = 0 ;
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
2010-09-30 21:31:19 +00:00
}
}
2018-10-04 13:26:41 +00:00
FlagModified ( sx , sy , l - > m_Width , l - > m_Height ) ;
2010-09-30 21:31:19 +00:00
}
2011-04-17 15:59:02 +00:00
void CLayerTele : : BrushFlipX ( )
{
CLayerTiles : : BrushFlipX ( ) ;
2022-06-05 20:21:24 +00:00
BrushFlipXImpl ( m_pTeleTile ) ;
2011-04-17 15:59:02 +00:00
}
void CLayerTele : : BrushFlipY ( )
{
CLayerTiles : : BrushFlipY ( ) ;
2022-06-05 20:21:24 +00:00
BrushFlipYImpl ( m_pTeleTile ) ;
2011-04-17 15:59:02 +00:00
}
void CLayerTele : : BrushRotate ( float Amount )
{
2020-09-26 19:41:58 +00:00
int Rotation = ( round_to_int ( 360.0f * Amount / ( pi * 2 ) ) / 90 ) % 4 ; // 0=0°, 1=90°, 2=180°, 3=270°
2011-04-17 15:59:02 +00:00
if ( Rotation < 0 )
2020-09-26 19:41:58 +00:00
Rotation + = 4 ;
2011-04-17 15:59:02 +00:00
if ( Rotation = = 1 | | Rotation = = 3 )
{
2014-03-19 09:26:38 +00:00
// 90° rotation
2020-09-26 19:41:58 +00:00
CTeleTile * pTempData1 = new CTeleTile [ m_Width * m_Height ] ;
CTile * pTempData2 = new CTile [ m_Width * m_Height ] ;
2020-10-05 17:03:14 +00:00
mem_copy ( pTempData1 , m_pTeleTile , ( size_t ) m_Width * m_Height * sizeof ( CTeleTile ) ) ;
mem_copy ( pTempData2 , m_pTiles , ( size_t ) m_Width * m_Height * sizeof ( CTile ) ) ;
2011-04-17 15:59:02 +00:00
CTeleTile * pDst1 = m_pTeleTile ;
CTile * pDst2 = m_pTiles ;
for ( int x = 0 ; x < m_Width ; + + x )
2020-09-26 19:41:58 +00:00
for ( int y = m_Height - 1 ; y > = 0 ; - - y , + + pDst1 , + + pDst2 )
2011-04-17 15:59:02 +00:00
{
2020-09-26 19:41:58 +00:00
* pDst1 = pTempData1 [ y * m_Width + x ] ;
* pDst2 = pTempData2 [ y * m_Width + x ] ;
2011-04-17 15:59:02 +00:00
}
2022-05-15 18:44:05 +00:00
std : : swap ( m_Width , m_Height ) ;
2011-04-17 15:59:02 +00:00
delete [ ] pTempData1 ;
delete [ ] pTempData2 ;
}
if ( Rotation = = 2 | | Rotation = = 3 )
{
BrushFlipX ( ) ;
BrushFlipY ( ) ;
}
}
2010-09-30 21:31:19 +00:00
void CLayerTele : : FillSelection ( bool Empty , CLayer * pBrush , CUIRect Rect )
{
2018-10-30 17:56:46 +00:00
if ( m_Readonly | | ( ! Empty & & pBrush - > m_Type ! = LAYERTYPE_TILES ) )
2018-09-26 12:53:25 +00:00
return ;
2015-07-09 00:08:14 +00:00
2014-03-12 22:34:30 +00:00
Snap ( & Rect ) ; // corrects Rect; no need of <=
2011-04-09 06:41:31 +00:00
2014-03-19 09:26:38 +00:00
Snap ( & Rect ) ;
2010-09-30 21:31:19 +00:00
int sx = ConvertX ( Rect . x ) ;
int sy = ConvertY ( Rect . y ) ;
int w = ConvertX ( Rect . w ) ;
int h = ConvertY ( Rect . h ) ;
2011-04-09 06:41:31 +00:00
2020-09-26 19:41:58 +00:00
CLayerTele * pLt = static_cast < CLayerTele * > ( pBrush ) ;
2011-04-09 06:41:31 +00:00
2019-04-30 12:24:13 +00:00
bool Destructive = m_pEditor - > m_BrushDrawDestructive | | Empty | | IsEmpty ( pLt ) ;
2019-03-26 18:15:24 +00:00
2014-03-19 09:26:38 +00:00
for ( int y = 0 ; y < h ; y + + )
2010-09-30 21:31:19 +00:00
{
2014-03-19 09:26:38 +00:00
for ( int x = 0 ; x < w ; x + + )
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
int fx = x + sx ;
int fy = y + sy ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
continue ;
2011-04-09 06:41:31 +00:00
2019-03-26 18:15:24 +00:00
if ( ! Destructive & & GetTile ( fx , fy ) . m_Index )
continue ;
2021-09-01 09:43:32 +00:00
if ( Empty | | ( ! m_pEditor - > m_AllowPlaceUnusedTiles & & ! IsValidTeleTile ( ( pLt - > m_pTiles [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] ) . m_Index ) ) )
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
m_pTeleTile [ fy * m_Width + fx ] . m_Type = 0 ;
m_pTeleTile [ fy * m_Width + fx ] . m_Number = 0 ;
2010-09-30 21:31:19 +00:00
}
2011-02-13 05:35:13 +00:00
else
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
m_pTiles [ fy * m_Width + fx ] = pLt - > m_pTiles [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] ;
if ( pLt - > m_Tele & & m_pTiles [ fy * m_Width + fx ] . m_Index > 0 )
2011-02-13 05:35:13 +00:00
{
2020-09-26 19:41:58 +00:00
if ( ( ! pLt - > m_pTeleTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Number & & m_pEditor - > m_TeleNumber ) | | m_pEditor - > m_TeleNumber ! = pLt - > m_TeleNum )
m_pTeleTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_TeleNumber ;
2010-12-07 15:51:59 +00:00
else
2020-09-26 19:41:58 +00:00
m_pTeleTile [ fy * m_Width + fx ] . m_Number = pLt - > m_pTeleTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Number ;
m_pTeleTile [ fy * m_Width + fx ] . m_Type = m_pTiles [ fy * m_Width + fx ] . m_Index ;
2011-02-13 05:35:13 +00:00
}
2010-09-30 21:31:19 +00:00
}
}
}
2018-10-04 13:26:41 +00:00
FlagModified ( sx , sy , w , h ) ;
2010-09-30 21:31:19 +00:00
}
2020-05-15 22:42:11 +00:00
bool CLayerTele : : ContainsElementWithId ( int Id )
{
for ( int y = 0 ; y < m_Height ; + + y )
{
for ( int x = 0 ; x < m_Width ; + + x )
{
2020-09-26 19:41:58 +00:00
if ( m_pTeleTile [ y * m_Width + x ] . m_Number = = Id )
2020-05-15 22:42:11 +00:00
{
return true ;
}
}
}
return false ;
}
2020-09-26 19:41:58 +00:00
CLayerSpeedup : : CLayerSpeedup ( int w , int h ) :
CLayerTiles ( w , h )
2010-09-30 21:31:19 +00:00
{
2011-08-26 16:46:27 +00:00
//m_Type = LAYERTYPE_SPEEDUP;
2011-08-13 00:12:40 +00:00
str_copy ( m_aName , " Speedup " , sizeof ( m_aName ) ) ;
2010-09-30 21:31:19 +00:00
m_Speedup = 1 ;
2011-04-09 06:41:31 +00:00
2020-09-26 19:41:58 +00:00
m_pSpeedupTile = new CSpeedupTile [ w * h ] ;
2020-10-05 17:03:14 +00:00
mem_zero ( m_pSpeedupTile , ( size_t ) w * h * sizeof ( CSpeedupTile ) ) ;
2010-09-30 21:31:19 +00:00
}
CLayerSpeedup : : ~ CLayerSpeedup ( )
{
delete [ ] m_pSpeedupTile ;
}
void CLayerSpeedup : : Resize ( int NewW , int NewH )
{
// resize speedup data
2020-09-26 19:41:58 +00:00
CSpeedupTile * pNewSpeedupData = new CSpeedupTile [ NewW * NewH ] ;
2020-10-05 17:03:14 +00:00
mem_zero ( pNewSpeedupData , ( size_t ) NewW * NewH * sizeof ( CSpeedupTile ) ) ;
2010-09-30 21:31:19 +00:00
2011-04-09 06:41:31 +00:00
// copy old data
2019-04-26 19:36:49 +00:00
for ( int y = 0 ; y < minimum ( NewH , m_Height ) ; y + + )
2020-09-26 19:41:58 +00:00
mem_copy ( & pNewSpeedupData [ y * NewW ] , & m_pSpeedupTile [ y * m_Width ] , minimum ( m_Width , NewW ) * sizeof ( CSpeedupTile ) ) ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
// replace old
2020-09-26 19:41:58 +00:00
delete [ ] m_pSpeedupTile ;
2010-09-30 21:31:19 +00:00
m_pSpeedupTile = pNewSpeedupData ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
// resize tile data
CLayerTiles : : Resize ( NewW , NewH ) ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
// resize gamelayer too
if ( m_pEditor - > m_Map . m_pGameLayer - > m_Width ! = NewW | | m_pEditor - > m_Map . m_pGameLayer - > m_Height ! = NewH )
m_pEditor - > m_Map . m_pGameLayer - > Resize ( NewW , NewH ) ;
}
2010-10-20 13:56:29 +00:00
void CLayerSpeedup : : Shift ( int Direction )
{
CLayerTiles : : Shift ( Direction ) ;
2022-06-05 20:03:16 +00:00
ShiftImpl ( m_pSpeedupTile , Direction , m_pEditor - > m_ShiftBy ) ;
2010-10-20 13:56:29 +00:00
}
2019-03-26 18:15:24 +00:00
bool CLayerSpeedup : : IsEmpty ( CLayerTiles * pLayer )
{
for ( int y = 0 ; y < pLayer - > m_Height ; y + + )
for ( int x = 0 ; x < pLayer - > m_Width ; x + + )
2021-09-01 09:43:32 +00:00
if ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidSpeedupTile ( pLayer - > GetTile ( x , y ) . m_Index ) )
2019-03-26 18:15:24 +00:00
return false ;
return true ;
}
2010-09-30 21:31:19 +00:00
void CLayerSpeedup : : BrushDraw ( CLayer * pBrush , float wx , float wy )
{
2011-08-26 16:46:27 +00:00
if ( m_Readonly )
return ;
2010-09-30 21:31:19 +00:00
CLayerSpeedup * l = ( CLayerSpeedup * ) pBrush ;
int sx = ConvertX ( wx ) ;
int sy = ConvertY ( wy ) ;
2010-12-19 14:10:42 +00:00
if ( str_comp ( l - > m_aFileName , m_pEditor - > m_aFileName ) )
{
m_pEditor - > m_SpeedupAngle = l - > m_SpeedupAngle ;
m_pEditor - > m_SpeedupForce = l - > m_SpeedupForce ;
m_pEditor - > m_SpeedupMaxSpeed = l - > m_SpeedupMaxSpeed ;
}
2011-04-09 06:41:31 +00:00
2019-03-26 18:15:24 +00:00
bool Destructive = m_pEditor - > m_BrushDrawDestructive | | IsEmpty ( l ) ;
2010-09-30 21:31:19 +00:00
for ( int y = 0 ; y < l - > m_Height ; y + + )
for ( int x = 0 ; x < l - > m_Width ; x + + )
{
2020-09-26 19:41:58 +00:00
int fx = x + sx ;
int fy = y + sy ;
2019-03-26 18:15:24 +00:00
2020-09-26 19:41:58 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
2010-09-30 21:31:19 +00:00
continue ;
2010-12-04 11:54:53 +00:00
2019-03-26 18:15:24 +00:00
if ( ! Destructive & & GetTile ( fx , fy ) . m_Index )
continue ;
2021-09-01 09:43:32 +00:00
if ( ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidSpeedupTile ( l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ) ) & & l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ! = TILE_AIR )
2010-09-30 21:31:19 +00:00
{
2010-12-04 11:54:53 +00:00
if ( m_pEditor - > m_SpeedupAngle ! = l - > m_SpeedupAngle | | m_pEditor - > m_SpeedupForce ! = l - > m_SpeedupForce | | m_pEditor - > m_SpeedupMaxSpeed ! = l - > m_SpeedupMaxSpeed )
{
2020-09-26 19:41:58 +00:00
m_pSpeedupTile [ fy * m_Width + fx ] . m_Force = m_pEditor - > m_SpeedupForce ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_MaxSpeed = m_pEditor - > m_SpeedupMaxSpeed ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Angle = m_pEditor - > m_SpeedupAngle ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Type = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
m_pTiles [ fy * m_Width + fx ] . m_Index = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
2010-12-04 11:54:53 +00:00
}
2020-09-26 19:41:58 +00:00
else if ( l - > m_pSpeedupTile [ y * l - > m_Width + x ] . m_Force )
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
m_pSpeedupTile [ fy * m_Width + fx ] . m_Force = l - > m_pSpeedupTile [ y * l - > m_Width + x ] . m_Force ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Angle = l - > m_pSpeedupTile [ y * l - > m_Width + x ] . m_Angle ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_MaxSpeed = l - > m_pSpeedupTile [ y * l - > m_Width + x ] . m_MaxSpeed ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Type = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
m_pTiles [ fy * m_Width + fx ] . m_Index = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
2010-09-30 21:31:19 +00:00
}
2010-12-04 11:54:53 +00:00
else if ( m_pEditor - > m_SpeedupForce )
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
m_pSpeedupTile [ fy * m_Width + fx ] . m_Force = m_pEditor - > m_SpeedupForce ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_MaxSpeed = m_pEditor - > m_SpeedupMaxSpeed ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Angle = m_pEditor - > m_SpeedupAngle ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Type = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
m_pTiles [ fy * m_Width + fx ] . m_Index = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
2010-09-30 21:31:19 +00:00
}
else
{
2020-09-10 22:42:42 +00:00
m_pSpeedupTile [ fy * m_Width + fx ] . m_Force = 0 ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_MaxSpeed = 0 ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Angle = 0 ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Type = 0 ;
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
2010-09-30 21:31:19 +00:00
}
}
else
{
2020-09-10 22:42:42 +00:00
m_pSpeedupTile [ fy * m_Width + fx ] . m_Force = 0 ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_MaxSpeed = 0 ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Angle = 0 ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Type = 0 ;
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
2010-09-30 21:31:19 +00:00
}
}
2018-10-04 13:26:41 +00:00
FlagModified ( sx , sy , l - > m_Width , l - > m_Height ) ;
2010-09-30 21:31:19 +00:00
}
2011-04-17 15:59:02 +00:00
void CLayerSpeedup : : BrushFlipX ( )
{
CLayerTiles : : BrushFlipX ( ) ;
2022-06-05 20:21:24 +00:00
BrushFlipXImpl ( m_pSpeedupTile ) ;
2011-04-17 15:59:02 +00:00
}
void CLayerSpeedup : : BrushFlipY ( )
{
CLayerTiles : : BrushFlipY ( ) ;
2022-06-05 20:21:24 +00:00
BrushFlipYImpl ( m_pSpeedupTile ) ;
2011-04-17 15:59:02 +00:00
}
void CLayerSpeedup : : BrushRotate ( float Amount )
{
2020-09-26 19:41:58 +00:00
int Rotation = ( round_to_int ( 360.0f * Amount / ( pi * 2 ) ) / 90 ) % 4 ; // 0=0°, 1=90°, 2=180°, 3=270°
2011-04-17 15:59:02 +00:00
if ( Rotation < 0 )
2020-09-26 19:41:58 +00:00
Rotation + = 4 ;
2011-04-17 15:59:02 +00:00
if ( Rotation = = 1 | | Rotation = = 3 )
{
2014-03-19 09:26:38 +00:00
// 90° rotation
2020-09-26 19:41:58 +00:00
CSpeedupTile * pTempData1 = new CSpeedupTile [ m_Width * m_Height ] ;
CTile * pTempData2 = new CTile [ m_Width * m_Height ] ;
2020-10-05 17:03:14 +00:00
mem_copy ( pTempData1 , m_pSpeedupTile , ( size_t ) m_Width * m_Height * sizeof ( CSpeedupTile ) ) ;
mem_copy ( pTempData2 , m_pTiles , ( size_t ) m_Width * m_Height * sizeof ( CTile ) ) ;
2011-04-17 15:59:02 +00:00
CSpeedupTile * pDst1 = m_pSpeedupTile ;
CTile * pDst2 = m_pTiles ;
for ( int x = 0 ; x < m_Width ; + + x )
2020-09-26 19:41:58 +00:00
for ( int y = m_Height - 1 ; y > = 0 ; - - y , + + pDst1 , + + pDst2 )
2011-04-17 15:59:02 +00:00
{
2020-09-26 19:41:58 +00:00
* pDst1 = pTempData1 [ y * m_Width + x ] ;
* pDst2 = pTempData2 [ y * m_Width + x ] ;
2011-04-17 15:59:02 +00:00
}
2022-05-15 18:44:05 +00:00
std : : swap ( m_Width , m_Height ) ;
2011-04-17 15:59:02 +00:00
delete [ ] pTempData1 ;
delete [ ] pTempData2 ;
}
if ( Rotation = = 2 | | Rotation = = 3 )
{
BrushFlipX ( ) ;
BrushFlipY ( ) ;
}
}
2010-09-30 21:31:19 +00:00
void CLayerSpeedup : : FillSelection ( bool Empty , CLayer * pBrush , CUIRect Rect )
{
2018-10-30 17:56:46 +00:00
if ( m_Readonly | | ( ! Empty & & pBrush - > m_Type ! = LAYERTYPE_TILES ) )
2018-09-26 12:53:25 +00:00
return ;
2015-07-09 00:08:14 +00:00
2014-03-12 22:34:30 +00:00
Snap ( & Rect ) ; // corrects Rect; no need of <=
2011-04-09 06:41:31 +00:00
2014-03-19 09:26:38 +00:00
Snap ( & Rect ) ;
2010-09-30 21:31:19 +00:00
int sx = ConvertX ( Rect . x ) ;
int sy = ConvertY ( Rect . y ) ;
int w = ConvertX ( Rect . w ) ;
int h = ConvertY ( Rect . h ) ;
2011-04-09 06:41:31 +00:00
2020-09-26 19:41:58 +00:00
CLayerSpeedup * pLt = static_cast < CLayerSpeedup * > ( pBrush ) ;
2011-04-09 06:41:31 +00:00
2019-04-30 12:24:13 +00:00
bool Destructive = m_pEditor - > m_BrushDrawDestructive | | Empty | | IsEmpty ( pLt ) ;
2019-03-26 18:15:24 +00:00
2014-03-19 09:26:38 +00:00
for ( int y = 0 ; y < h ; y + + )
2010-09-30 21:31:19 +00:00
{
2014-03-19 09:26:38 +00:00
for ( int x = 0 ; x < w ; x + + )
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
int fx = x + sx ;
int fy = y + sy ;
2011-04-09 06:41:31 +00:00
2010-09-30 21:31:19 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
continue ;
2011-04-09 06:41:31 +00:00
2019-03-26 18:15:24 +00:00
if ( ! Destructive & & GetTile ( fx , fy ) . m_Index )
continue ;
2021-09-01 09:43:32 +00:00
if ( Empty | | ( ! m_pEditor - > m_AllowPlaceUnusedTiles & & ! IsValidSpeedupTile ( ( pLt - > m_pTiles [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] ) . m_Index ) ) ) // no speed up tile chosen: reset
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Force = 0 ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Angle = 0 ;
2010-09-30 21:31:19 +00:00
}
2011-02-13 05:35:13 +00:00
else
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
m_pTiles [ fy * m_Width + fx ] = pLt - > m_pTiles [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] ;
if ( pLt - > m_Speedup & & m_pTiles [ fy * m_Width + fx ] . m_Index > 0 )
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
if ( ( ! pLt - > m_pSpeedupTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Force & & m_pEditor - > m_SpeedupForce ) | | m_pEditor - > m_SpeedupForce ! = pLt - > m_SpeedupForce )
m_pSpeedupTile [ fy * m_Width + fx ] . m_Force = m_pEditor - > m_SpeedupForce ;
2010-12-07 15:51:59 +00:00
else
2020-09-26 19:41:58 +00:00
m_pSpeedupTile [ fy * m_Width + fx ] . m_Force = pLt - > m_pSpeedupTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Force ;
if ( ( ! pLt - > m_pSpeedupTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Angle & & m_pEditor - > m_SpeedupAngle ) | | m_pEditor - > m_SpeedupAngle ! = pLt - > m_SpeedupAngle )
m_pSpeedupTile [ fy * m_Width + fx ] . m_Angle = m_pEditor - > m_SpeedupAngle ;
2010-12-07 15:51:59 +00:00
else
2020-09-26 19:41:58 +00:00
m_pSpeedupTile [ fy * m_Width + fx ] . m_Angle = pLt - > m_pSpeedupTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Angle ;
if ( ( ! pLt - > m_pSpeedupTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_MaxSpeed & & m_pEditor - > m_SpeedupMaxSpeed ) | | m_pEditor - > m_SpeedupMaxSpeed ! = pLt - > m_SpeedupMaxSpeed )
m_pSpeedupTile [ fy * m_Width + fx ] . m_MaxSpeed = m_pEditor - > m_SpeedupMaxSpeed ;
2010-12-07 15:51:59 +00:00
else
2020-09-26 19:41:58 +00:00
m_pSpeedupTile [ fy * m_Width + fx ] . m_MaxSpeed = pLt - > m_pSpeedupTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_MaxSpeed ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Type = m_pTiles [ fy * m_Width + fx ] . m_Index ;
2010-09-30 21:31:19 +00:00
}
}
}
}
2018-10-04 13:26:41 +00:00
FlagModified ( sx , sy , w , h ) ;
2010-09-30 21:31:19 +00:00
}
2020-09-26 19:41:58 +00:00
CLayerFront : : CLayerFront ( int w , int h ) :
CLayerTiles ( w , h )
2010-09-30 21:31:19 +00:00
{
2011-08-26 16:46:27 +00:00
//m_Type = LAYERTYPE_FRONT;
2011-08-13 00:12:40 +00:00
str_copy ( m_aName , " Front " , sizeof ( m_aName ) ) ;
2010-09-30 21:31:19 +00:00
m_Front = 1 ;
}
2016-04-30 23:47:29 +00:00
void CLayerFront : : SetTile ( int x , int y , CTile tile )
2015-11-14 23:00:43 +00:00
{
2020-09-26 19:41:58 +00:00
if ( tile . m_Index = = TILE_THROUGH_CUT )
{
2016-04-30 23:47:29 +00:00
CTile nohook = { TILE_NOHOOK } ;
2020-11-04 18:27:22 +00:00
m_pEditor - > m_Map . m_pGameLayer - > CLayerTiles : : SetTile ( x , y , nohook ) ; // NOLINT(bugprone-parent-virtual-call)
2020-09-26 19:41:58 +00:00
}
else if ( tile . m_Index = = TILE_AIR & & CLayerTiles : : GetTile ( x , y ) . m_Index = = TILE_THROUGH_CUT )
{
2016-04-30 23:47:29 +00:00
CTile air = { TILE_AIR } ;
2020-11-04 18:27:22 +00:00
m_pEditor - > m_Map . m_pGameLayer - > CLayerTiles : : SetTile ( x , y , air ) ; // NOLINT(bugprone-parent-virtual-call)
2016-04-30 23:47:29 +00:00
}
2020-09-26 19:41:58 +00:00
if ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidFrontTile ( tile . m_Index ) )
{
2016-04-30 23:47:29 +00:00
CLayerTiles : : SetTile ( x , y , tile ) ;
2020-09-26 19:41:58 +00:00
}
else
{
2016-04-30 23:47:29 +00:00
CTile air = { TILE_AIR } ;
CLayerTiles : : SetTile ( x , y , air ) ;
2020-09-26 19:41:58 +00:00
if ( ! m_pEditor - > m_PreventUnusedTilesWasWarned )
{
2016-05-01 16:08:07 +00:00
m_pEditor - > m_PopupEventType = m_pEditor - > POPEVENT_PREVENTUNUSEDTILES ;
m_pEditor - > m_PopupEventActivated = true ;
m_pEditor - > m_PreventUnusedTilesWasWarned = true ;
}
2016-04-29 14:53:19 +00:00
}
2015-11-14 23:00:43 +00:00
}
2010-09-30 21:31:19 +00:00
void CLayerFront : : Resize ( int NewW , int NewH )
{
// resize tile data
CLayerTiles : : Resize ( NewW , NewH ) ;
// resize gamelayer too
if ( m_pEditor - > m_Map . m_pGameLayer - > m_Width ! = NewW | | m_pEditor - > m_Map . m_pGameLayer - > m_Height ! = NewH )
m_pEditor - > m_Map . m_pGameLayer - > Resize ( NewW , NewH ) ;
}
2020-09-26 19:41:58 +00:00
CLayerSwitch : : CLayerSwitch ( int w , int h ) :
CLayerTiles ( w , h )
2010-09-30 21:31:19 +00:00
{
2011-08-26 16:46:27 +00:00
//m_Type = LAYERTYPE_SWITCH;
2011-08-13 00:12:40 +00:00
str_copy ( m_aName , " Switch " , sizeof ( m_aName ) ) ;
2010-09-30 21:31:19 +00:00
m_Switch = 1 ;
2020-09-26 19:41:58 +00:00
m_pSwitchTile = new CSwitchTile [ w * h ] ;
2020-10-05 17:03:14 +00:00
mem_zero ( m_pSwitchTile , ( size_t ) w * h * sizeof ( CSwitchTile ) ) ;
2010-09-30 21:31:19 +00:00
}
CLayerSwitch : : ~ CLayerSwitch ( )
{
delete [ ] m_pSwitchTile ;
}
void CLayerSwitch : : Resize ( int NewW , int NewH )
{
// resize switch data
2020-09-26 19:41:58 +00:00
CSwitchTile * pNewSwitchData = new CSwitchTile [ NewW * NewH ] ;
2020-10-05 17:03:14 +00:00
mem_zero ( pNewSwitchData , ( size_t ) NewW * NewH * sizeof ( CSwitchTile ) ) ;
2010-09-30 21:31:19 +00:00
// copy old data
2019-04-26 19:36:49 +00:00
for ( int y = 0 ; y < minimum ( NewH , m_Height ) ; y + + )
2020-09-26 19:41:58 +00:00
mem_copy ( & pNewSwitchData [ y * NewW ] , & m_pSwitchTile [ y * m_Width ] , minimum ( m_Width , NewW ) * sizeof ( CSwitchTile ) ) ;
2010-09-30 21:31:19 +00:00
// replace old
2020-09-26 19:41:58 +00:00
delete [ ] m_pSwitchTile ;
2010-09-30 21:31:19 +00:00
m_pSwitchTile = pNewSwitchData ;
// resize tile data
CLayerTiles : : Resize ( NewW , NewH ) ;
// resize gamelayer too
if ( m_pEditor - > m_Map . m_pGameLayer - > m_Width ! = NewW | | m_pEditor - > m_Map . m_pGameLayer - > m_Height ! = NewH )
m_pEditor - > m_Map . m_pGameLayer - > Resize ( NewW , NewH ) ;
}
2010-10-22 15:02:11 +00:00
void CLayerSwitch : : Shift ( int Direction )
{
CLayerTiles : : Shift ( Direction ) ;
2022-06-05 20:03:16 +00:00
ShiftImpl ( m_pSwitchTile , Direction , m_pEditor - > m_ShiftBy ) ;
2010-10-22 15:02:11 +00:00
}
2019-03-26 18:15:24 +00:00
bool CLayerSwitch : : IsEmpty ( CLayerTiles * pLayer )
{
for ( int y = 0 ; y < pLayer - > m_Height ; y + + )
for ( int x = 0 ; x < pLayer - > m_Width ; x + + )
2021-09-01 09:43:32 +00:00
if ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidSwitchTile ( pLayer - > GetTile ( x , y ) . m_Index ) )
2019-03-26 18:15:24 +00:00
return false ;
return true ;
}
2010-09-30 21:31:19 +00:00
void CLayerSwitch : : BrushDraw ( CLayer * pBrush , float wx , float wy )
{
2011-08-26 16:46:27 +00:00
if ( m_Readonly )
return ;
2010-09-30 21:31:19 +00:00
CLayerSwitch * l = ( CLayerSwitch * ) pBrush ;
int sx = ConvertX ( wx ) ;
int sy = ConvertY ( wy ) ;
2010-12-19 14:10:42 +00:00
if ( str_comp ( l - > m_aFileName , m_pEditor - > m_aFileName ) )
{
m_pEditor - > m_SwitchNum = l - > m_SwitchNumber ;
m_pEditor - > m_SwitchDelay = l - > m_SwitchDelay ;
}
2010-09-30 21:31:19 +00:00
2019-03-26 18:15:24 +00:00
bool Destructive = m_pEditor - > m_BrushDrawDestructive | | IsEmpty ( l ) ;
2010-09-30 21:31:19 +00:00
for ( int y = 0 ; y < l - > m_Height ; y + + )
for ( int x = 0 ; x < l - > m_Width ; x + + )
{
2020-09-26 19:41:58 +00:00
int fx = x + sx ;
int fy = y + sy ;
2019-03-26 18:15:24 +00:00
2020-09-26 19:41:58 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
2010-09-30 21:31:19 +00:00
continue ;
2019-03-26 18:15:24 +00:00
if ( ! Destructive & & GetTile ( fx , fy ) . m_Index )
continue ;
2021-09-01 09:43:32 +00:00
if ( ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidSwitchTile ( l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ) ) & & l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ! = TILE_AIR )
2010-09-30 21:31:19 +00:00
{
2010-12-07 15:51:59 +00:00
if ( m_pEditor - > m_SwitchNum ! = l - > m_SwitchNumber | | m_pEditor - > m_SwitchDelay ! = l - > m_SwitchDelay )
2010-12-04 11:54:53 +00:00
{
2020-09-26 19:41:58 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_SwitchNum ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = m_pEditor - > m_SwitchDelay ;
2010-12-04 11:54:53 +00:00
}
2020-09-26 19:41:58 +00:00
else if ( l - > m_pSwitchTile [ y * l - > m_Width + x ] . m_Number )
2010-12-04 11:54:53 +00:00
{
2020-09-26 19:41:58 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = l - > m_pSwitchTile [ y * l - > m_Width + x ] . m_Number ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = l - > m_pSwitchTile [ y * l - > m_Width + x ] . m_Delay ;
2010-12-04 11:54:53 +00:00
}
else
2010-09-30 21:31:19 +00:00
{
2020-09-26 19:41:58 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_SwitchNum ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = m_pEditor - > m_SwitchDelay ;
2010-09-30 21:31:19 +00:00
}
2020-09-26 19:41:58 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Type = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Flags = l - > m_pTiles [ y * l - > m_Width + x ] . m_Flags ;
m_pTiles [ fy * m_Width + fx ] . m_Index = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
m_pTiles [ fy * m_Width + fx ] . m_Flags = l - > m_pTiles [ y * l - > m_Width + x ] . m_Flags ;
2010-09-30 21:31:19 +00:00
}
else
{
2020-09-26 19:41:58 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = 0 ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Type = 0 ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Flags = 0 ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = 0 ;
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
2010-09-30 21:31:19 +00:00
}
2011-01-25 09:34:14 +00:00
2020-09-26 19:41:58 +00:00
if ( l - > m_pTiles [ y * l - > m_Width + x ] . m_Index = = TILE_FREEZE )
2011-01-25 09:34:14 +00:00
{
2020-09-26 19:41:58 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Flags = 0 ;
2011-01-25 09:34:14 +00:00
}
2020-09-26 19:41:58 +00:00
else if ( l - > m_pTiles [ y * l - > m_Width + x ] . m_Index = = TILE_DFREEZE | | l - > m_pTiles [ y * l - > m_Width + x ] . m_Index = = TILE_DUNFREEZE )
2011-01-25 09:34:14 +00:00
{
2020-09-26 19:41:58 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Flags = 0 ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = 0 ;
2011-01-25 09:34:14 +00:00
}
2010-09-30 21:31:19 +00:00
}
2018-10-04 13:26:41 +00:00
FlagModified ( sx , sy , l - > m_Width , l - > m_Height ) ;
2010-09-30 21:31:19 +00:00
}
2019-03-21 21:50:22 +00:00
void CLayerSwitch : : BrushFlipX ( )
{
CLayerTiles : : BrushFlipX ( ) ;
2022-06-05 20:21:24 +00:00
BrushFlipXImpl ( m_pSwitchTile ) ;
2019-03-21 21:50:22 +00:00
}
void CLayerSwitch : : BrushFlipY ( )
{
CLayerTiles : : BrushFlipY ( ) ;
2022-06-05 20:21:24 +00:00
BrushFlipYImpl ( m_pSwitchTile ) ;
2019-03-21 21:50:22 +00:00
}
void CLayerSwitch : : BrushRotate ( float Amount )
{
2020-09-26 19:41:58 +00:00
int Rotation = ( round_to_int ( 360.0f * Amount / ( pi * 2 ) ) / 90 ) % 4 ; // 0=0°, 1=90°, 2=180°, 3=270°
2019-03-21 21:50:22 +00:00
if ( Rotation < 0 )
2020-09-26 19:41:58 +00:00
Rotation + = 4 ;
2019-03-21 21:50:22 +00:00
if ( Rotation = = 1 | | Rotation = = 3 )
{
// 90° rotation
2020-09-26 19:41:58 +00:00
CSwitchTile * pTempData1 = new CSwitchTile [ m_Width * m_Height ] ;
CTile * pTempData2 = new CTile [ m_Width * m_Height ] ;
2020-10-05 17:03:14 +00:00
mem_copy ( pTempData1 , m_pSwitchTile , ( size_t ) m_Width * m_Height * sizeof ( CSwitchTile ) ) ;
mem_copy ( pTempData2 , m_pTiles , ( size_t ) m_Width * m_Height * sizeof ( CTile ) ) ;
2019-03-21 21:50:22 +00:00
CSwitchTile * pDst1 = m_pSwitchTile ;
CTile * pDst2 = m_pTiles ;
for ( int x = 0 ; x < m_Width ; + + x )
2020-09-26 19:41:58 +00:00
for ( int y = m_Height - 1 ; y > = 0 ; - - y , + + pDst1 , + + pDst2 )
2019-03-21 21:50:22 +00:00
{
2020-09-26 19:41:58 +00:00
* pDst1 = pTempData1 [ y * m_Width + x ] ;
* pDst2 = pTempData2 [ y * m_Width + x ] ;
2020-01-17 17:22:41 +00:00
if ( IsRotatableTile ( pDst2 - > m_Index ) )
{
2020-09-26 19:41:58 +00:00
if ( pDst2 - > m_Flags & TILEFLAG_ROTATE )
pDst2 - > m_Flags ^ = ( TILEFLAG_HFLIP | TILEFLAG_VFLIP ) ;
2020-01-17 17:22:41 +00:00
pDst2 - > m_Flags ^ = TILEFLAG_ROTATE ;
}
2019-03-21 21:50:22 +00:00
}
2022-05-15 18:44:05 +00:00
std : : swap ( m_Width , m_Height ) ;
2019-03-21 21:50:22 +00:00
delete [ ] pTempData1 ;
delete [ ] pTempData2 ;
}
if ( Rotation = = 2 | | Rotation = = 3 )
{
BrushFlipX ( ) ;
BrushFlipY ( ) ;
}
}
2010-09-30 21:31:19 +00:00
void CLayerSwitch : : FillSelection ( bool Empty , CLayer * pBrush , CUIRect Rect )
2010-11-23 09:26:54 +00:00
{
2018-10-30 17:56:46 +00:00
if ( m_Readonly | | ( ! Empty & & pBrush - > m_Type ! = LAYERTYPE_TILES ) )
2018-09-26 12:53:25 +00:00
return ;
2015-07-09 00:08:14 +00:00
2014-03-12 22:34:30 +00:00
Snap ( & Rect ) ; // corrects Rect; no need of <=
2010-11-23 09:26:54 +00:00
2014-03-19 09:26:38 +00:00
Snap ( & Rect ) ;
2010-11-23 09:26:54 +00:00
int sx = ConvertX ( Rect . x ) ;
int sy = ConvertY ( Rect . y ) ;
int w = ConvertX ( Rect . w ) ;
int h = ConvertY ( Rect . h ) ;
2020-09-26 19:41:58 +00:00
CLayerSwitch * pLt = static_cast < CLayerSwitch * > ( pBrush ) ;
2010-11-23 09:26:54 +00:00
2019-04-30 12:24:13 +00:00
bool Destructive = m_pEditor - > m_BrushDrawDestructive | | Empty | | IsEmpty ( pLt ) ;
2019-03-26 18:15:24 +00:00
2014-03-19 09:26:38 +00:00
for ( int y = 0 ; y < h ; y + + )
2010-11-23 09:26:54 +00:00
{
2014-03-19 09:26:38 +00:00
for ( int x = 0 ; x < w ; x + + )
2010-11-23 09:26:54 +00:00
{
2020-09-26 19:41:58 +00:00
int fx = x + sx ;
int fy = y + sy ;
2010-11-23 09:26:54 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
continue ;
2019-03-26 18:15:24 +00:00
if ( ! Destructive & & GetTile ( fx , fy ) . m_Index )
continue ;
2021-09-01 09:43:32 +00:00
if ( Empty | | ( ! m_pEditor - > m_AllowPlaceUnusedTiles & & ! IsValidSwitchTile ( ( pLt - > m_pTiles [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] ) . m_Index ) ) )
2010-11-23 09:26:54 +00:00
{
2020-09-26 19:41:58 +00:00
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Type = 0 ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = 0 ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = 0 ;
2010-11-23 09:26:54 +00:00
}
2018-09-26 12:53:25 +00:00
else
2010-11-23 09:26:54 +00:00
{
2020-09-26 19:41:58 +00:00
m_pTiles [ fy * m_Width + fx ] = pLt - > m_pTiles [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Type = m_pTiles [ fy * m_Width + fx ] . m_Index ;
if ( pLt - > m_Switch & & m_pEditor - > m_SwitchNum & & m_pTiles [ fy * m_Width + fx ] . m_Index > 0 )
2011-02-13 05:35:13 +00:00
{
2020-09-26 19:41:58 +00:00
if ( ( ! pLt - > m_pSwitchTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Number ) | | m_pEditor - > m_SwitchNum ! = pLt - > m_SwitchNumber )
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_SwitchNum ;
2010-12-07 15:51:59 +00:00
else
2020-09-26 19:41:58 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = pLt - > m_pSwitchTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Number ;
if ( ( ! pLt - > m_pSwitchTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Delay ) | | m_pEditor - > m_SwitchDelay ! = pLt - > m_SwitchDelay )
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = m_pEditor - > m_SwitchDelay ;
2010-12-07 15:51:59 +00:00
else
2020-09-26 19:41:58 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = pLt - > m_pSwitchTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Delay ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Flags = pLt - > m_pSwitchTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Flags ;
2011-02-13 05:35:13 +00:00
}
2010-11-23 09:26:54 +00:00
}
}
}
2018-10-04 13:26:41 +00:00
FlagModified ( sx , sy , w , h ) ;
2010-11-23 09:26:54 +00:00
}
2014-03-12 22:34:30 +00:00
2020-05-17 00:56:35 +00:00
bool CLayerSwitch : : ContainsElementWithId ( int Id )
{
for ( int y = 0 ; y < m_Height ; + + y )
{
for ( int x = 0 ; x < m_Width ; + + x )
{
2020-09-26 19:41:58 +00:00
if ( m_pSwitchTile [ y * m_Width + x ] . m_Number = = Id )
2020-05-17 00:56:35 +00:00
{
return true ;
}
}
}
return false ;
}
2014-03-12 22:34:30 +00:00
//------------------------------------------------------
2020-09-26 19:41:58 +00:00
CLayerTune : : CLayerTune ( int w , int h ) :
CLayerTiles ( w , h )
2014-03-12 22:34:30 +00:00
{
2018-07-25 20:57:58 +00:00
//m_Type = LAYERTYPE_TUNE;
2014-03-12 22:34:30 +00:00
str_copy ( m_aName , " Tune " , sizeof ( m_aName ) ) ;
m_Tune = 1 ;
2020-09-26 19:41:58 +00:00
m_pTuneTile = new CTuneTile [ w * h ] ;
2020-10-05 17:03:14 +00:00
mem_zero ( m_pTuneTile , ( size_t ) w * h * sizeof ( CTuneTile ) ) ;
2014-03-12 22:34:30 +00:00
}
CLayerTune : : ~ CLayerTune ( )
{
delete [ ] m_pTuneTile ;
}
void CLayerTune : : Resize ( int NewW , int NewH )
{
// resize Tune data
2020-09-26 19:41:58 +00:00
CTuneTile * pNewTuneData = new CTuneTile [ NewW * NewH ] ;
2020-10-05 17:03:14 +00:00
mem_zero ( pNewTuneData , ( size_t ) NewW * NewH * sizeof ( CTuneTile ) ) ;
2014-03-12 22:34:30 +00:00
// copy old data
2019-04-26 19:36:49 +00:00
for ( int y = 0 ; y < minimum ( NewH , m_Height ) ; y + + )
2020-09-26 19:41:58 +00:00
mem_copy ( & pNewTuneData [ y * NewW ] , & m_pTuneTile [ y * m_Width ] , minimum ( m_Width , NewW ) * sizeof ( CTuneTile ) ) ;
2014-03-12 22:34:30 +00:00
// replace old
2020-09-26 19:41:58 +00:00
delete [ ] m_pTuneTile ;
2014-03-12 22:34:30 +00:00
m_pTuneTile = pNewTuneData ;
// resize tile data
CLayerTiles : : Resize ( NewW , NewH ) ;
// resize gamelayer too
if ( m_pEditor - > m_Map . m_pGameLayer - > m_Width ! = NewW | | m_pEditor - > m_Map . m_pGameLayer - > m_Height ! = NewH )
m_pEditor - > m_Map . m_pGameLayer - > Resize ( NewW , NewH ) ;
}
void CLayerTune : : Shift ( int Direction )
{
CLayerTiles : : Shift ( Direction ) ;
2022-06-05 20:03:16 +00:00
ShiftImpl ( m_pTuneTile , Direction , m_pEditor - > m_ShiftBy ) ;
2014-03-12 22:34:30 +00:00
}
2019-03-26 18:15:24 +00:00
bool CLayerTune : : IsEmpty ( CLayerTiles * pLayer )
{
for ( int y = 0 ; y < pLayer - > m_Height ; y + + )
for ( int x = 0 ; x < pLayer - > m_Width ; x + + )
2021-09-01 09:43:32 +00:00
if ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidTuneTile ( pLayer - > GetTile ( x , y ) . m_Index ) )
2019-03-26 18:15:24 +00:00
return false ;
return true ;
}
2014-03-12 22:34:30 +00:00
void CLayerTune : : BrushDraw ( CLayer * pBrush , float wx , float wy )
{
if ( m_Readonly )
return ;
CLayerTune * l = ( CLayerTune * ) pBrush ;
int sx = ConvertX ( wx ) ;
int sy = ConvertY ( wy ) ;
if ( str_comp ( l - > m_aFileName , m_pEditor - > m_aFileName ) )
{
m_pEditor - > m_TuningNum = l - > m_TuningNumber ;
}
2019-03-26 18:15:24 +00:00
bool Destructive = m_pEditor - > m_BrushDrawDestructive | | IsEmpty ( l ) ;
2014-03-12 22:34:30 +00:00
for ( int y = 0 ; y < l - > m_Height ; y + + )
2020-09-26 19:41:58 +00:00
for ( int x = 0 ; x < l - > m_Width ; x + + )
{
int fx = x + sx ;
int fy = y + sy ;
2019-03-26 18:15:24 +00:00
2020-09-26 19:41:58 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
continue ;
2014-03-12 22:34:30 +00:00
2020-09-26 19:41:58 +00:00
if ( ! Destructive & & GetTile ( fx , fy ) . m_Index )
continue ;
2019-03-26 18:15:24 +00:00
2021-09-01 09:43:32 +00:00
if ( ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidTuneTile ( l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ) ) & & l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ! = TILE_AIR )
2020-09-26 19:41:58 +00:00
{
if ( m_pEditor - > m_TuningNum ! = l - > m_TuningNumber )
2014-03-12 22:34:30 +00:00
{
2020-09-26 19:41:58 +00:00
m_pTuneTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_TuningNum ;
2014-03-12 22:34:30 +00:00
}
2020-09-26 19:41:58 +00:00
else if ( l - > m_pTuneTile [ y * l - > m_Width + x ] . m_Number )
m_pTuneTile [ fy * m_Width + fx ] . m_Number = l - > m_pTuneTile [ y * l - > m_Width + x ] . m_Number ;
2014-03-12 22:34:30 +00:00
else
{
2020-09-26 19:41:58 +00:00
if ( ! m_pEditor - > m_TuningNum )
{
m_pTuneTile [ fy * m_Width + fx ] . m_Number = 0 ;
m_pTuneTile [ fy * m_Width + fx ] . m_Type = 0 ;
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
continue ;
}
else
m_pTuneTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_TuningNum ;
2014-03-12 22:34:30 +00:00
}
2020-09-26 19:41:58 +00:00
m_pTuneTile [ fy * m_Width + fx ] . m_Type = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
m_pTiles [ fy * m_Width + fx ] . m_Index = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
2014-03-12 22:34:30 +00:00
}
2020-09-26 19:41:58 +00:00
else
{
m_pTuneTile [ fy * m_Width + fx ] . m_Number = 0 ;
m_pTuneTile [ fy * m_Width + fx ] . m_Type = 0 ;
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
}
}
2018-10-04 13:26:41 +00:00
FlagModified ( sx , sy , l - > m_Width , l - > m_Height ) ;
2014-03-12 22:34:30 +00:00
}
void CLayerTune : : BrushFlipX ( )
{
CLayerTiles : : BrushFlipX ( ) ;
2022-06-05 20:21:24 +00:00
BrushFlipXImpl ( m_pTuneTile ) ;
2014-03-12 22:34:30 +00:00
}
void CLayerTune : : BrushFlipY ( )
{
CLayerTiles : : BrushFlipY ( ) ;
2022-06-05 20:21:24 +00:00
BrushFlipYImpl ( m_pTuneTile ) ;
2014-03-12 22:34:30 +00:00
}
void CLayerTune : : BrushRotate ( float Amount )
{
2020-09-26 19:41:58 +00:00
int Rotation = ( round_to_int ( 360.0f * Amount / ( pi * 2 ) ) / 90 ) % 4 ; // 0=0°, 1=90°, 2=180°, 3=270°
2014-03-12 22:34:30 +00:00
if ( Rotation < 0 )
2020-09-26 19:41:58 +00:00
Rotation + = 4 ;
2014-03-12 22:34:30 +00:00
if ( Rotation = = 1 | | Rotation = = 3 )
{
2014-03-23 16:42:00 +00:00
// 90° rotation
2020-09-26 19:41:58 +00:00
CTuneTile * pTempData1 = new CTuneTile [ m_Width * m_Height ] ;
CTile * pTempData2 = new CTile [ m_Width * m_Height ] ;
2020-10-05 17:03:14 +00:00
mem_copy ( pTempData1 , m_pTuneTile , ( size_t ) m_Width * m_Height * sizeof ( CTuneTile ) ) ;
mem_copy ( pTempData2 , m_pTiles , ( size_t ) m_Width * m_Height * sizeof ( CTile ) ) ;
2014-03-12 22:34:30 +00:00
CTuneTile * pDst1 = m_pTuneTile ;
CTile * pDst2 = m_pTiles ;
for ( int x = 0 ; x < m_Width ; + + x )
2020-09-26 19:41:58 +00:00
for ( int y = m_Height - 1 ; y > = 0 ; - - y , + + pDst1 , + + pDst2 )
2014-03-12 22:34:30 +00:00
{
2020-09-26 19:41:58 +00:00
* pDst1 = pTempData1 [ y * m_Width + x ] ;
* pDst2 = pTempData2 [ y * m_Width + x ] ;
2014-03-12 22:34:30 +00:00
}
2022-05-15 18:44:05 +00:00
std : : swap ( m_Width , m_Height ) ;
2014-03-12 22:34:30 +00:00
delete [ ] pTempData1 ;
delete [ ] pTempData2 ;
}
if ( Rotation = = 2 | | Rotation = = 3 )
{
BrushFlipX ( ) ;
BrushFlipY ( ) ;
}
}
void CLayerTune : : FillSelection ( bool Empty , CLayer * pBrush , CUIRect Rect )
{
2018-10-30 17:56:46 +00:00
if ( m_Readonly | | ( ! Empty & & pBrush - > m_Type ! = LAYERTYPE_TILES ) )
2018-09-26 12:53:25 +00:00
return ;
2015-07-09 00:08:14 +00:00
2014-03-12 22:34:30 +00:00
Snap ( & Rect ) ; // corrects Rect; no need of <=
2020-09-26 19:41:58 +00:00
int sx = ConvertX ( Rect . x ) ;
int sy = ConvertY ( Rect . y ) ;
int w = ConvertX ( Rect . w ) ;
int h = ConvertY ( Rect . h ) ;
2014-03-12 22:34:30 +00:00
2020-09-26 19:41:58 +00:00
CLayerTune * pLt = static_cast < CLayerTune * > ( pBrush ) ;
2014-03-12 22:34:30 +00:00
2020-09-26 19:41:58 +00:00
bool Destructive = m_pEditor - > m_BrushDrawDestructive | | Empty | | IsEmpty ( pLt ) ;
2019-03-26 18:15:24 +00:00
2020-09-26 19:41:58 +00:00
for ( int y = 0 ; y < h ; y + + )
{
for ( int x = 0 ; x < w ; x + + )
2014-03-12 22:34:30 +00:00
{
2020-09-26 19:41:58 +00:00
int fx = x + sx ;
int fy = y + sy ;
2014-03-12 22:34:30 +00:00
2020-09-26 19:41:58 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
continue ;
2014-03-12 22:34:30 +00:00
2020-09-26 19:41:58 +00:00
if ( ! Destructive & & GetTile ( fx , fy ) . m_Index )
continue ;
2019-03-26 18:15:24 +00:00
2021-09-01 09:43:32 +00:00
if ( Empty | | ( ! m_pEditor - > m_AllowPlaceUnusedTiles & & ! IsValidTuneTile ( ( pLt - > m_pTiles [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] ) . m_Index ) ) ) // \o/ this fixes editor bug; TODO: use IsUsedInThisLayer here
2020-09-26 19:41:58 +00:00
{
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
m_pTuneTile [ fy * m_Width + fx ] . m_Type = 0 ;
m_pTuneTile [ fy * m_Width + fx ] . m_Number = 0 ;
}
else
{
m_pTiles [ fy * m_Width + fx ] = pLt - > m_pTiles [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] ;
if ( pLt - > m_Tune & & m_pTiles [ fy * m_Width + fx ] . m_Index > 0 )
2014-03-12 22:34:30 +00:00
{
2020-09-26 19:41:58 +00:00
if ( ( ! pLt - > m_pTuneTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Number & & m_pEditor - > m_TuningNum ) | | m_pEditor - > m_TuningNum ! = pLt - > m_TuningNumber )
m_pTuneTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_TuningNum ;
else
m_pTuneTile [ fy * m_Width + fx ] . m_Number = pLt - > m_pTuneTile [ ( y * pLt - > m_Width + x % pLt - > m_Width ) % ( pLt - > m_Width * pLt - > m_Height ) ] . m_Number ;
m_pTuneTile [ fy * m_Width + fx ] . m_Type = m_pTiles [ fy * m_Width + fx ] . m_Index ;
2014-03-12 22:34:30 +00:00
}
}
}
2020-09-26 19:41:58 +00:00
}
2018-10-04 13:26:41 +00:00
FlagModified ( sx , sy , w , h ) ;
2014-03-23 16:42:00 +00:00
}