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>
2020-02-27 13:53:12 +00:00
# include <base/tl/algorithm.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
2010-05-29 07:25:38 +00:00
# include <game/generated/client_data.h>
# include <game/client/render.h>
2011-04-19 08:34:51 +00:00
# include "editor.h"
2008-01-12 12:27:55 +00:00
2010-06-05 21:36:52 +00:00
# include <game/localization.h>
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
2010-05-29 07:25:38 +00:00
m_pTiles = new CTile [ m_Width * m_Height ] ;
mem_zero ( m_pTiles , 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
{
2010-05-29 07:25:38 +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
{
return m_pTiles [ y * m_Width + x ] ;
}
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
{
m_pTiles [ y * m_Width + x ] = tile ;
}
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 + + )
2010-09-05 17:01:01 +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 + + )
m_pTiles [ y * m_Width + x ] . m_Flags | = m_pEditor - > m_Map . m_lImages [ 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 + + )
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
{
2010-05-29 07:25:38 +00:00
if ( m_Image > = 0 & & m_Image < m_pEditor - > m_Map . m_lImages . size ( ) )
2012-08-12 10:41:50 +00:00
m_Texture = m_pEditor - > m_Map . m_lImages [ m_Image ] - > m_Texture ;
Graphics ( ) - > TextureSet ( m_Texture ) ;
2019-04-26 22:11:15 +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 ,
m_pEditor - > EnvelopeEval , m_pEditor , m_ColorEnv , m_ColorEnvOffset ) ;
Graphics ( ) - > BlendNormal ( ) ;
m_pEditor - > RenderTools ( ) - > RenderTilemap ( m_pTiles , m_Width , m_Height , 32.0f , Color , LAYERRENDERFLAG_TRANSPARENT ,
2011-08-13 00:12:40 +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 )
m_pEditor - > RenderTools ( ) - > RenderTeleOverlay ( ( ( CLayerTele * ) this ) - > m_pTeleTile , m_Width , m_Height , 32.0f ) ;
if ( m_Speedup )
m_pEditor - > RenderTools ( ) - > RenderSpeedupOverlay ( ( ( CLayerSpeedup * ) this ) - > m_pSpeedupTile , m_Width , m_Height , 32.0f ) ;
if ( m_Switch )
m_pEditor - > RenderTools ( ) - > RenderSwitchOverlay ( ( ( CLayerSwitch * ) this ) - > m_pSwitchTile , m_Width , m_Height , 32.0f ) ;
if ( m_Tune )
m_pEditor - > RenderTools ( ) - > RenderTuneOverlay ( ( ( CLayerTune * ) this ) - > m_pTuneTile , m_Width , m_Height , 32.0f ) ;
}
2008-01-12 12:27:55 +00:00
}
2010-05-29 07:25:38 +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 ) ;
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 ) ;
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
2010-05-29 07:25:38 +00:00
if ( pRect - > x + pRect - > w > m_Width )
pRect - > w = m_Width - pRect - > x ;
2008-01-12 12:27:55 +00:00
2010-05-29 07:25:38 +00:00
if ( pRect - > y + pRect - > h > m_Height )
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 ) ) ;
2011-05-04 23:50:23 +00:00
TextRender ( ) - > Text ( 0 , Rect . x + 3.0f , Rect . y + 3.0f , m_pEditor - > m_ShowPicker ? 15.0f : 15.0f * m_pEditor - > m_WorldZoom , aBuf , - 1 ) ;
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 ;
2018-09-11 08:35:02 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
{
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 + + )
2015-11-14 23:00:43 +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 + + )
{
pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] = ( ( CLayerTele * ) this ) - > m_pTeleTile [ ( r . y + y ) * m_Width + ( r . x + x ) ] ;
2014-02-01 21:20:41 +00:00
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 )
2010-12-07 15:51:59 +00:00
m_pEditor - > m_TeleNumber = pGrabbed - > m_pTeleTile [ y * pGrabbed - > m_Width + x ] . m_Number ;
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 ;
2018-09-11 08:35:02 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
{
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 + + )
2015-11-14 23:00:43 +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 + + )
{
pGrabbed - > m_pSpeedupTile [ y * pGrabbed - > m_Width + x ] = ( ( CLayerSpeedup * ) this ) - > m_pSpeedupTile [ ( r . y + y ) * m_Width + ( r . x + x ) ] ;
2010-11-01 12:29:56 +00:00
if ( pGrabbed - > m_pSpeedupTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_BOOST )
2010-09-30 21:31:19 +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-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 ;
2018-09-11 08:35:02 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
{
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 + + )
2015-11-14 23:00:43 +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 + + )
{
pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] = ( ( CLayerSwitch * ) this ) - > m_pSwitchTile [ ( r . y + y ) * m_Width + ( r . x + x ) ] ;
2018-10-26 14:43:02 +00:00
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_START
| | pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_HIT_END
| | 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_PENALTY
| | pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Type = = TILE_BONUS
2018-11-02 23:02:20 +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
{
2010-09-30 21:31:19 +00:00
m_pEditor - > m_SwitchNum = pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Number ;
2010-11-22 20:43:22 +00:00
m_pEditor - > m_SwitchDelay = pGrabbed - > m_pSwitchTile [ y * pGrabbed - > m_Width + x ] . m_Delay ;
}
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 ;
2018-09-11 08:35:02 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
{
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 + + )
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 + + )
{
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_TUNE1 )
{
m_pEditor - > m_TuningNum = pGrabbed - > m_pTuneTile [ y * pGrabbed - > m_Width + x ] . m_Number ;
}
}
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 ;
2018-09-11 08:35:02 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
{
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 + + )
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 ;
2018-09-11 08:35:02 +00:00
if ( m_pEditor - > m_BrushColorEnabled )
{
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 + + )
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
2010-05-29 07:25:38 +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
{
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 )
2019-04-30 12:24:13 +00:00
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
2011-04-13 18:37:12 +00:00
else
2015-11-14 23:00:43 +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
{
int fx = x + sx ;
int fy = y + sy ;
2019-03-26 18:15:24 +00:00
2010-05-29 07:25:38 +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
{
2010-05-29 07:25:38 +00:00
for ( int y = 0 ; y < m_Height ; y + + )
for ( int x = 0 ; x < m_Width / 2 ; x + + )
2008-01-12 12:27:55 +00:00
{
2010-05-29 07:25:38 +00:00
CTile Tmp = m_pTiles [ y * m_Width + x ] ;
m_pTiles [ y * m_Width + x ] = m_pTiles [ y * m_Width + m_Width - 1 - x ] ;
m_pTiles [ y * m_Width + m_Width - 1 - x ] = Tmp ;
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 + + )
2019-03-21 21:50:22 +00:00
if ( ! Rotate & & ! IsRotatableTile ( m_pTiles [ y * m_Width + x ] . m_Index ) )
m_pTiles [ y * m_Width + x ] . m_Flags = 0 ;
else
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
{
2010-05-29 07:25:38 +00:00
for ( int y = 0 ; y < m_Height / 2 ; y + + )
for ( int x = 0 ; x < m_Width ; x + + )
2008-01-12 12:27:55 +00:00
{
2010-05-29 07:25:38 +00:00
CTile Tmp = m_pTiles [ y * m_Width + x ] ;
m_pTiles [ y * m_Width + x ] = m_pTiles [ ( m_Height - 1 - y ) * m_Width + x ] ;
m_pTiles [ ( m_Height - 1 - y ) * m_Width + x ] = Tmp ;
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 + + )
2019-03-21 21:50:22 +00:00
if ( ! Rotate & & ! IsRotatableTile ( m_pTiles [ y * m_Width + x ] . m_Index ) )
m_pTiles [ y * m_Width + x ] . m_Flags = 0 ;
else
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 )
{
2014-04-22 21:46:55 +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 )
Rotation + = 4 ;
if ( Rotation = = 1 | | Rotation = = 3 )
{
2014-03-19 09:26:38 +00:00
// 90° rotation
2010-09-05 17:01:01 +00:00
CTile * pTempData = new CTile [ m_Width * m_Height ] ;
mem_copy ( pTempData , m_pTiles , m_Width * m_Height * sizeof ( CTile ) ) ;
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 )
for ( int y = m_Height - 1 ; y > = 0 ; - - y , + + pDst )
{
* 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
{
if ( pDst - > m_Flags & TILEFLAG_ROTATE )
pDst - > m_Flags ^ = ( TILEFLAG_HFLIP | TILEFLAG_VFLIP ) ;
pDst - > m_Flags ^ = TILEFLAG_ROTATE ;
}
2010-09-05 17:01:01 +00:00
}
int Temp = m_Width ;
m_Width = m_Height ;
m_Height = Temp ;
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
{
2010-05-29 07:25:38 +00:00
CTile * pNewData = new CTile [ NewW * NewH ] ;
mem_zero ( pNewData , 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 + + )
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
2010-05-29 07:25:38 +00:00
delete [ ] m_pTiles ;
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 )
{
2014-05-31 23:32:54 +00:00
int o = m_pEditor - > m_ShiftBy ;
2010-10-09 16:38:23 +00:00
switch ( Direction )
{
case 1 :
{
// left
for ( int y = 0 ; y < m_Height ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_move ( & m_pTiles [ y * m_Width ] , & m_pTiles [ y * m_Width + o ] , ( m_Width - o ) * sizeof ( CTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTiles [ y * m_Width + ( m_Width - o ) ] , o * sizeof ( CTile ) ) ;
}
2010-10-09 16:38:23 +00:00
}
break ;
case 2 :
{
// right
for ( int y = 0 ; y < m_Height ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_move ( & m_pTiles [ y * m_Width + o ] , & m_pTiles [ y * m_Width ] , ( m_Width - o ) * sizeof ( CTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTiles [ y * m_Width ] , o * sizeof ( CTile ) ) ;
}
2010-10-09 16:38:23 +00:00
}
break ;
case 4 :
{
// up
2014-05-31 23:32:54 +00:00
for ( int y = 0 ; y < m_Height - o ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_copy ( & m_pTiles [ y * m_Width ] , & m_pTiles [ ( y + o ) * m_Width ] , m_Width * sizeof ( CTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTiles [ ( y + o ) * m_Width ] , m_Width * sizeof ( CTile ) ) ;
}
2010-10-09 16:38:23 +00:00
}
break ;
case 8 :
{
// down
2014-06-01 11:16:25 +00:00
for ( int y = m_Height - 1 ; y > = o ; - - y )
{
2014-05-31 23:32:54 +00:00
mem_copy ( & m_pTiles [ y * m_Width ] , & m_pTiles [ ( y - o ) * m_Width ] , m_Width * sizeof ( CTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTiles [ ( y - o ) * m_Width ] , m_Width * sizeof ( CTile ) ) ;
}
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
2019-04-26 19:36:49 +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 + + )
{
int c = x + y * m_Width ;
if ( m_pTiles [ c ] . m_Index )
{
char aBuf [ 64 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " %i " , m_pTiles [ c ] . m_Index ) ;
2012-10-14 12:04:48 +00:00
m_pEditor - > Graphics ( ) - > QuadsText ( x * 32 , y * 32 , 16.0f , aBuf ) ;
2011-02-18 10:41:27 +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 } ;
2012-10-14 12:04:48 +00:00
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
2019-03-12 01:35:29 +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
2019-03-12 01:35:29 +00:00
CLayerGroup * pGroup = m_pEditor - > m_Map . m_lGroups [ m_pEditor - > m_SelectedGroup ] ;
// 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
{
2011-02-13 05:35:13 +00:00
case 4 :
2016-05-04 20:33:10 +00:00
Result = TILE_THROUGH_CUT ;
2011-02-13 05:35:13 +00:00
break ;
case 5 :
2016-05-04 20:33:10 +00:00
Result = TILE_FREEZE ;
2011-02-13 05:35:13 +00:00
break ;
case 6 :
2016-05-04 20:33:10 +00:00
Result = TILE_UNFREEZE ;
2011-02-13 05:35:13 +00:00
break ;
case 7 :
2016-05-04 20:33:10 +00:00
Result = TILE_DFREEZE ;
2011-02-13 05:35:13 +00:00
break ;
2014-02-12 20:44:05 +00:00
case 8 :
2016-05-04 20:33:10 +00:00
Result = TILE_DUNFREEZE ;
2014-02-12 20:44:05 +00:00
break ;
case 9 :
2016-05-04 20:33:10 +00:00
Result = TILE_TELECHECKIN ;
2014-02-12 20:44:05 +00:00
break ;
2016-05-01 15:44:02 +00:00
case 10 :
2016-05-04 20:33:10 +00:00
Result = TILE_TELECHECKINEVIL ;
2011-02-13 05:35:13 +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
{
2019-03-12 01:35:29 +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 )
{
if ( m_Image > = 0 & & m_Image < m_pEditor - > m_Map . m_lImages . size ( ) & & m_pEditor - > m_Map . m_lImages [ m_Image ] - > m_AutoMapper . IsLoaded ( ) & &
m_AutoMapperConfig ! = - 1 )
{
static int s_AutoMapperButton = 0 ;
static int s_AutoMapperButtonAuto = 0 ;
pToolBox - > HSplitBottom ( 2.0f , pToolBox , 0 ) ;
pToolBox - > HSplitBottom ( 12.0f , pToolBox , & Button ) ;
if ( m_Seed ! = 0 ) {
CUIRect ButtonAuto ;
Button . VSplitRight ( 16.0f , & Button , & ButtonAuto ) ;
Button . VSplitRight ( 2.0f , & Button , 0 ) ;
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 " ) )
{
m_pEditor - > m_Map . m_lImages [ m_Image ] - > m_AutoMapper . Proceed ( this , m_AutoMapperConfig , m_Seed ) ;
return 1 ;
}
}
}
2011-04-13 18:37:12 +00:00
2008-01-12 12:27:55 +00:00
enum
{
2008-03-21 00:13:55 +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 ;
Color | = m_Color . r < < 24 ;
Color | = m_Color . g < < 16 ;
Color | = m_Color . b < < 8 ;
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 } ,
2011-03-20 16:04:03 +00:00
{ " Image " , m_Image , PROPTYPE_IMAGE , 0 , 0 } ,
{ " Color " , Color , PROPTYPE_COLOR , 0 , 0 } ,
2020-01-23 19:26:06 +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 } ,
2008-01-12 12:27:55 +00:00
{ 0 } ,
} ;
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
{
2018-10-03 16:16:58 +00:00
aProps [ PROP_IMAGE ] . m_pName = 0 ;
aProps [ PROP_COLOR ] . m_pName = 0 ;
aProps [ PROP_AUTOMAPPER ] . m_pName = 0 ;
}
if ( m_Image = = - 1 )
{
aProps [ PROP_AUTOMAPPER ] . m_pName = 0 ;
aProps [ PROP_SEED ] . m_pName = 0 ;
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
{
2010-05-29 07:25:38 +00:00
if ( NewVal = = - 1 )
2008-09-07 08:30:49 +00:00
{
2012-08-12 10:41:50 +00:00
m_Texture = IGraphics : : CTextureHandle ( ) ;
2010-05-29 07:25:38 +00:00
m_Image = - 1 ;
2008-09-07 08:30:49 +00:00
}
else
2018-10-03 16:16:58 +00:00
{
2010-05-29 07:25:38 +00:00
m_Image = NewVal % m_pEditor - > m_Map . m_lImages . size ( ) ;
2018-10-03 16:16:58 +00:00
m_AutoMapperConfig = - 1 ;
}
2008-09-07 08:30:49 +00:00
}
2011-01-04 10:38:14 +00:00
else if ( Prop = = PROP_COLOR )
{
m_Color . r = ( NewVal > > 24 ) & 0xff ;
m_Color . g = ( NewVal > > 16 ) & 0xff ;
m_Color . b = ( NewVal > > 8 ) & 0xff ;
m_Color . a = NewVal & 0xff ;
}
2011-07-18 10:05:12 +00:00
if ( Prop = = PROP_COLOR_ENV )
2011-08-06 20:30:18 +00:00
{
int Index = clamp ( NewVal - 1 , - 1 , m_pEditor - > m_Map . m_lEnvelopes . size ( ) - 1 ) ;
int Step = ( Index - m_ColorEnv ) % 2 ;
if ( Step ! = 0 )
{
for ( ; Index > = - 1 & & Index < m_pEditor - > m_Map . m_lEnvelopes . size ( ) ; Index + = Step )
if ( Index = = - 1 | | m_pEditor - > m_Map . m_lEnvelopes [ Index ] - > m_Channels = = 4 )
{
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 )
{
2018-10-08 20:44:49 +00:00
if ( m_Image > = 0 & & m_pEditor - > m_Map . m_lImages [ m_Image ] - > m_AutoMapper . ConfigNamesNum ( ) > 0 & & NewVal > = 0 )
2018-10-03 16:16:58 +00:00
m_AutoMapperConfig = NewVal % m_pEditor - > m_Map . m_lImages [ m_Image ] - > m_AutoMapper . ConfigNamesNum ( ) ;
else
m_AutoMapperConfig = - 1 ;
}
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
2020-02-27 13:53:12 +00:00
int CLayerTiles : : RenderCommonProperties ( CEditor * pEditor , CUIRect * pToolbox , array < CLayerTiles * > & pLayers )
{
enum
{
PROP_WIDTH = 0 ,
PROP_HEIGHT ,
PROP_SHIFT ,
NUM_PROPS ,
} ;
int m_Width = 1 ;
int m_Height = 1 ;
CProperty aProps [ ] = {
{ " Width " , m_Width , PROPTYPE_INT_SCROLL , 1 , 100000 } ,
{ " Height " , m_Height , PROPTYPE_INT_SCROLL , 1 , 100000 } ,
{ " Shift " , 0 , PROPTYPE_SHIFT , 0 , 0 } ,
{ 0 } ,
} ;
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 ;
}
for_each ( pLayers . all ( ) , [ NewVal ] ( CLayerTiles * pLayer ) {
pLayer - > Resize ( NewVal , pLayer - > m_Height ) ;
} ) ;
}
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 ;
}
for_each ( pLayers . all ( ) , [ NewVal ] ( CLayerTiles * pLayer ) {
pLayer - > Resize ( pLayer - > m_Width , NewVal ) ;
} ) ;
}
else if ( Prop = = PROP_SHIFT )
{
for_each ( pLayers . all ( ) , [ NewVal ] ( CLayerTiles * pLayer ) {
pLayer - > Shift ( NewVal ) ;
} ) ;
}
if ( Prop ! = - 1 )
{
for_each ( pLayers . all ( ) , [ ] ( CLayerTiles * pLayer ) {
pLayer - > FlagModified ( 0 , 0 , pLayer - > m_Width , pLayer - > m_Height ) ;
} ) ;
}
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 ;
2018-10-03 16:16:58 +00:00
if ( m_Seed ! = 0 & & m_AutoMapperConfig ! = - 1 & & m_AutoAutoMap ) {
2018-10-04 13:26:41 +00:00
m_pEditor - > m_Map . m_lImages [ m_Image ] - > m_AutoMapper . ProceedLocalized ( this , m_AutoMapperConfig , m_Seed , x , y , w , h ) ;
2018-10-03 16:16:58 +00:00
}
}
2008-01-19 12:32:08 +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
CLayerTele : : CLayerTele ( int w , int h )
: CLayerTiles ( w , h )
{
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
2010-09-30 21:31:19 +00:00
m_pTeleTile = new CTeleTile [ w * h ] ;
mem_zero ( m_pTeleTile , w * h * sizeof ( CTeleTile ) ) ;
}
CLayerTele : : ~ CLayerTele ( )
{
delete [ ] m_pTeleTile ;
}
void CLayerTele : : Resize ( int NewW , int NewH )
{
// resize tele data
CTeleTile * pNewTeleData = new CTeleTile [ NewW * NewH ] ;
mem_zero ( pNewTeleData , NewW * NewH * sizeof ( CTeleTile ) ) ;
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 + + )
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
delete [ ] m_pTeleTile ;
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 ) ;
2014-05-31 23:32:54 +00:00
int o = m_pEditor - > m_ShiftBy ;
2011-04-09 06:41:31 +00:00
2010-10-20 13:56:29 +00:00
switch ( Direction )
{
case 1 :
{
// left
for ( int y = 0 ; y < m_Height ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_move ( & m_pTeleTile [ y * m_Width ] , & m_pTeleTile [ y * m_Width + o ] , ( m_Width - o ) * sizeof ( CTeleTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTeleTile [ y * m_Width + ( m_Width - o ) ] , o * sizeof ( CTeleTile ) ) ;
}
2010-10-20 13:56:29 +00:00
}
break ;
case 2 :
{
// right
for ( int y = 0 ; y < m_Height ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_move ( & m_pTeleTile [ y * m_Width + o ] , & m_pTeleTile [ y * m_Width ] , ( m_Width - o ) * sizeof ( CTeleTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTeleTile [ y * m_Width ] , o * sizeof ( CTeleTile ) ) ;
}
2010-10-20 13:56:29 +00:00
}
break ;
case 4 :
{
// up
2014-05-31 23:32:54 +00:00
for ( int y = 0 ; y < m_Height - o ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_copy ( & m_pTeleTile [ y * m_Width ] , & m_pTeleTile [ ( y + o ) * m_Width ] , m_Width * sizeof ( CTeleTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTeleTile [ ( y + o ) * m_Width ] , m_Width * sizeof ( CTeleTile ) ) ;
}
2010-10-20 13:56:29 +00:00
}
break ;
case 8 :
{
// down
2014-06-01 11:16:25 +00:00
for ( int y = m_Height - 1 ; y > = o ; - - y )
{
2014-05-31 23:32:54 +00:00
mem_copy ( & m_pTeleTile [ y * m_Width ] , & m_pTeleTile [ ( y - o ) * m_Width ] , m_Width * sizeof ( CTeleTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTeleTile [ ( y - o ) * m_Width ] , m_Width * sizeof ( CTeleTile ) ) ;
}
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 + + )
if ( IsValidTeleTile ( pLayer - > GetTile ( x , y ) . m_Index ) )
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 + + )
{
int fx = x + sx ;
int fy = y + sy ;
2019-03-26 18:15:24 +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 ;
if ( IsValidTeleTile ( l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ) )
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
{
2010-12-07 15:51:59 +00:00
m_pTeleTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_TeleNumber ;
2010-12-04 11:54:53 +00:00
}
else if ( l - > m_pTeleTile [ y * l - > m_Width + x ] . m_Number )
2010-09-30 21:31:19 +00:00
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
{
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 ;
continue ;
}
else
2010-12-07 15:51:59 +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
2010-09-30 21:31:19 +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 ;
}
else
{
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 ;
}
}
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 ( ) ;
for ( int y = 0 ; y < m_Height ; y + + )
for ( int x = 0 ; x < m_Width / 2 ; x + + )
{
CTeleTile Tmp = m_pTeleTile [ y * m_Width + x ] ;
m_pTeleTile [ y * m_Width + x ] = m_pTeleTile [ y * m_Width + m_Width - 1 - x ] ;
m_pTeleTile [ y * m_Width + m_Width - 1 - x ] = Tmp ;
}
}
void CLayerTele : : BrushFlipY ( )
{
CLayerTiles : : BrushFlipY ( ) ;
for ( int y = 0 ; y < m_Height / 2 ; y + + )
for ( int x = 0 ; x < m_Width ; x + + )
{
CTeleTile Tmp = m_pTeleTile [ y * m_Width + x ] ;
m_pTeleTile [ y * m_Width + x ] = m_pTeleTile [ ( m_Height - 1 - y ) * m_Width + x ] ;
m_pTeleTile [ ( m_Height - 1 - y ) * m_Width + x ] = Tmp ;
}
}
void CLayerTele : : BrushRotate ( float Amount )
{
2014-04-22 21:46:55 +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 )
Rotation + = 4 ;
if ( Rotation = = 1 | | Rotation = = 3 )
{
2014-03-19 09:26:38 +00:00
// 90° rotation
2011-04-17 15:59:02 +00:00
CTeleTile * pTempData1 = new CTeleTile [ m_Width * m_Height ] ;
CTile * pTempData2 = new CTile [ m_Width * m_Height ] ;
mem_copy ( pTempData1 , m_pTeleTile , m_Width * m_Height * sizeof ( CTeleTile ) ) ;
mem_copy ( pTempData2 , m_pTiles , m_Width * m_Height * sizeof ( CTile ) ) ;
CTeleTile * pDst1 = m_pTeleTile ;
CTile * pDst2 = m_pTiles ;
for ( int x = 0 ; x < m_Width ; + + x )
for ( int y = m_Height - 1 ; y > = 0 ; - - y , + + pDst1 , + + pDst2 )
{
* pDst1 = pTempData1 [ y * m_Width + x ] ;
* pDst2 = pTempData2 [ y * m_Width + x ] ;
}
int Temp = m_Width ;
m_Width = m_Height ;
m_Height = Temp ;
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
2010-09-30 21:31:19 +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
{
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 ;
if ( Empty | | ! 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
{
2011-02-13 05:35:13 +00:00
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
2010-12-07 15:51:59 +00:00
m_pTeleTile [ fy * m_Width + fx ] . m_Type = 0 ;
2010-09-30 21:31:19 +00:00
m_pTeleTile [ fy * m_Width + fx ] . m_Number = 0 ;
}
2011-02-13 05:35:13 +00:00
else
2010-09-30 21:31:19 +00:00
{
2011-02-13 05:35:13 +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 ) ] ;
2018-09-26 12:53:25 +00:00
if ( pLt - > m_Tele & & m_pTiles [ fy * m_Width + fx ] . m_Index > 0 )
2011-02-13 05:35:13 +00:00
{
2010-12-07 15:51:59 +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 ;
else
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 ;
2018-09-26 12:53:25 +00:00
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
}
CLayerSpeedup : : CLayerSpeedup ( int w , int h )
: CLayerTiles ( w , h )
{
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
2010-09-30 21:31:19 +00:00
m_pSpeedupTile = new CSpeedupTile [ w * h ] ;
mem_zero ( m_pSpeedupTile , w * h * sizeof ( CSpeedupTile ) ) ;
}
CLayerSpeedup : : ~ CLayerSpeedup ( )
{
delete [ ] m_pSpeedupTile ;
}
void CLayerSpeedup : : Resize ( int NewW , int NewH )
{
// resize speedup data
CSpeedupTile * pNewSpeedupData = new CSpeedupTile [ NewW * NewH ] ;
mem_zero ( pNewSpeedupData , NewW * NewH * sizeof ( CSpeedupTile ) ) ;
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 + + )
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
delete [ ] m_pSpeedupTile ;
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 ) ;
2014-05-31 23:32:54 +00:00
int o = m_pEditor - > m_ShiftBy ;
2011-04-09 06:41:31 +00:00
2010-10-20 13:56:29 +00:00
switch ( Direction )
{
case 1 :
{
// left
for ( int y = 0 ; y < m_Height ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_move ( & m_pSpeedupTile [ y * m_Width ] , & m_pSpeedupTile [ y * m_Width + o ] , ( m_Width - o ) * sizeof ( CSpeedupTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pSpeedupTile [ y * m_Width + ( m_Width - o ) ] , o * sizeof ( CSpeedupTile ) ) ;
}
2010-10-20 13:56:29 +00:00
}
break ;
case 2 :
{
// right
for ( int y = 0 ; y < m_Height ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_move ( & m_pSpeedupTile [ y * m_Width + o ] , & m_pSpeedupTile [ y * m_Width ] , ( m_Width - o ) * sizeof ( CSpeedupTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pSpeedupTile [ y * m_Width ] , o * sizeof ( CSpeedupTile ) ) ;
}
2010-10-20 13:56:29 +00:00
}
break ;
case 4 :
{
// up
2014-05-31 23:32:54 +00:00
for ( int y = 0 ; y < m_Height - o ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_copy ( & m_pSpeedupTile [ y * m_Width ] , & m_pSpeedupTile [ ( y + o ) * m_Width ] , m_Width * sizeof ( CSpeedupTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pSpeedupTile [ ( y + o ) * m_Width ] , m_Width * sizeof ( CSpeedupTile ) ) ;
}
2010-10-20 13:56:29 +00:00
}
break ;
case 8 :
{
// down
2014-06-01 11:16:25 +00:00
for ( int y = m_Height - 1 ; y > = o ; - - y )
{
2014-05-31 23:32:54 +00:00
mem_copy ( & m_pSpeedupTile [ y * m_Width ] , & m_pSpeedupTile [ ( y - o ) * m_Width ] , m_Width * sizeof ( CSpeedupTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pSpeedupTile [ ( y - o ) * m_Width ] , m_Width * sizeof ( CSpeedupTile ) ) ;
}
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 + + )
if ( IsValidSpeedupTile ( pLayer - > GetTile ( x , y ) . m_Index ) )
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 + + )
{
int fx = x + sx ;
int fy = y + sy ;
2019-03-26 18:15:24 +00:00
2010-09-30 21:31:19 +00:00
if ( fx < 0 | | fx > = m_Width | | fy < 0 | | fy > = m_Height )
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 ;
if ( IsValidSpeedupTile ( 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
if ( m_pEditor - > m_SpeedupAngle ! = l - > m_SpeedupAngle | | m_pEditor - > m_SpeedupForce ! = l - > m_SpeedupForce | | m_pEditor - > m_SpeedupMaxSpeed ! = l - > m_SpeedupMaxSpeed )
{
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 ;
}
else if ( l - > m_pSpeedupTile [ y * l - > m_Width + x ] . m_Force )
2010-09-30 21:31:19 +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 ;
2010-12-04 11:54:53 +00:00
m_pSpeedupTile [ fy * m_Width + fx ] . m_MaxSpeed = l - > m_pSpeedupTile [ y * l - > m_Width + x ] . m_MaxSpeed ;
2010-09-30 21:31:19 +00:00
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
else if ( m_pEditor - > m_SpeedupForce )
2010-09-30 21:31:19 +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 ;
}
else
{
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_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
}
}
else
{
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_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 ) ;
2010-09-30 21:31:19 +00:00
}
2011-04-17 15:59:02 +00:00
void CLayerSpeedup : : BrushFlipX ( )
{
CLayerTiles : : BrushFlipX ( ) ;
for ( int y = 0 ; y < m_Height ; y + + )
for ( int x = 0 ; x < m_Width / 2 ; x + + )
{
CSpeedupTile Tmp = m_pSpeedupTile [ y * m_Width + x ] ;
m_pSpeedupTile [ y * m_Width + x ] = m_pSpeedupTile [ y * m_Width + m_Width - 1 - x ] ;
m_pSpeedupTile [ y * m_Width + m_Width - 1 - x ] = Tmp ;
}
}
void CLayerSpeedup : : BrushFlipY ( )
{
CLayerTiles : : BrushFlipY ( ) ;
for ( int y = 0 ; y < m_Height / 2 ; y + + )
for ( int x = 0 ; x < m_Width ; x + + )
{
CSpeedupTile Tmp = m_pSpeedupTile [ y * m_Width + x ] ;
m_pSpeedupTile [ y * m_Width + x ] = m_pSpeedupTile [ ( m_Height - 1 - y ) * m_Width + x ] ;
m_pSpeedupTile [ ( m_Height - 1 - y ) * m_Width + x ] = Tmp ;
}
}
void CLayerSpeedup : : BrushRotate ( float Amount )
{
2014-04-22 21:46:55 +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 )
Rotation + = 4 ;
if ( Rotation = = 1 | | Rotation = = 3 )
{
2014-03-19 09:26:38 +00:00
// 90° rotation
2011-04-17 15:59:02 +00:00
CSpeedupTile * pTempData1 = new CSpeedupTile [ m_Width * m_Height ] ;
CTile * pTempData2 = new CTile [ m_Width * m_Height ] ;
mem_copy ( pTempData1 , m_pSpeedupTile , m_Width * m_Height * sizeof ( CSpeedupTile ) ) ;
mem_copy ( pTempData2 , m_pTiles , m_Width * m_Height * sizeof ( CTile ) ) ;
CSpeedupTile * pDst1 = m_pSpeedupTile ;
CTile * pDst2 = m_pTiles ;
for ( int x = 0 ; x < m_Width ; + + x )
for ( int y = m_Height - 1 ; y > = 0 ; - - y , + + pDst1 , + + pDst2 )
{
* pDst1 = pTempData1 [ y * m_Width + x ] ;
* pDst2 = pTempData2 [ y * m_Width + x ] ;
}
int Temp = m_Width ;
m_Width = m_Height ;
m_Height = Temp ;
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
2010-09-30 21:31:19 +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
{
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 ;
if ( Empty | | ! 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
{
2011-02-13 05:35:13 +00:00
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
2010-09-30 21:31:19 +00:00
m_pSpeedupTile [ fy * m_Width + fx ] . m_Force = 0 ;
m_pSpeedupTile [ fy * m_Width + fx ] . m_Angle = 0 ;
}
2011-02-13 05:35:13 +00:00
else
2010-09-30 21:31:19 +00:00
{
2011-02-13 05:35:13 +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 ) ] ;
2018-09-26 12:53:25 +00:00
if ( pLt - > m_Speedup & & m_pTiles [ fy * m_Width + fx ] . m_Index > 0 )
2010-09-30 21:31:19 +00:00
{
2010-12-07 15:51:59 +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 ;
else
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 ;
else
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 ;
else
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 ;
2018-09-26 12:53:25 +00:00
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
}
CLayerFront : : CLayerFront ( int w , int h )
: CLayerTiles ( w , h )
{
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
{
2016-04-30 23:47:29 +00:00
if ( tile . m_Index = = TILE_THROUGH_CUT ) {
CTile nohook = { TILE_NOHOOK } ;
m_pEditor - > m_Map . m_pGameLayer - > CLayerTiles : : SetTile ( x , y , nohook ) ;
} else if ( tile . m_Index = = TILE_AIR & & CLayerTiles : : GetTile ( x , y ) . m_Index = = TILE_THROUGH_CUT ) {
CTile air = { TILE_AIR } ;
m_pEditor - > m_Map . m_pGameLayer - > CLayerTiles : : SetTile ( x , y , air ) ;
}
if ( m_pEditor - > m_AllowPlaceUnusedTiles | | IsValidFrontTile ( tile . m_Index ) ) {
CLayerTiles : : SetTile ( x , y , tile ) ;
} else {
CTile air = { TILE_AIR } ;
CLayerTiles : : SetTile ( x , y , air ) ;
2016-05-01 16:08:07 +00:00
if ( ! m_pEditor - > m_PreventUnusedTilesWasWarned ) {
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 ) ;
}
CLayerSwitch : : CLayerSwitch ( int w , int h )
: CLayerTiles ( w , h )
{
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 ;
2010-11-13 13:22:19 +00:00
m_pSwitchTile = new CSwitchTile [ w * h ] ;
mem_zero ( m_pSwitchTile , 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
2010-11-13 13:22:19 +00:00
CSwitchTile * pNewSwitchData = new CSwitchTile [ NewW * NewH ] ;
mem_zero ( pNewSwitchData , 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 + + )
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
delete [ ] m_pSwitchTile ;
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 ) ;
2014-05-31 23:32:54 +00:00
int o = m_pEditor - > m_ShiftBy ;
2010-10-22 15:02:11 +00:00
switch ( Direction )
{
case 1 :
{
// left
for ( int y = 0 ; y < m_Height ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_move ( & m_pSwitchTile [ y * m_Width ] , & m_pSwitchTile [ y * m_Width + o ] , ( m_Width - o ) * sizeof ( CSwitchTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pSwitchTile [ y * m_Width + ( m_Width - o ) ] , o * sizeof ( CSwitchTile ) ) ;
}
2010-10-22 15:02:11 +00:00
}
break ;
case 2 :
{
// right
for ( int y = 0 ; y < m_Height ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_move ( & m_pSwitchTile [ y * m_Width + o ] , & m_pSwitchTile [ y * m_Width ] , ( m_Width - o ) * sizeof ( CSwitchTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pSwitchTile [ y * m_Width ] , o * sizeof ( CSwitchTile ) ) ;
}
2010-10-22 15:02:11 +00:00
}
break ;
case 4 :
{
// up
2014-05-31 23:32:54 +00:00
for ( int y = 0 ; y < m_Height - o ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_copy ( & m_pSwitchTile [ y * m_Width ] , & m_pSwitchTile [ ( y + o ) * m_Width ] , m_Width * sizeof ( CSwitchTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pSwitchTile [ ( y + o ) * m_Width ] , m_Width * sizeof ( CSwitchTile ) ) ;
}
2010-10-22 15:02:11 +00:00
}
break ;
case 8 :
{
// down
2014-06-01 11:16:25 +00:00
for ( int y = m_Height - 1 ; y > = o ; - - y )
{
2014-05-31 23:32:54 +00:00
mem_copy ( & m_pSwitchTile [ y * m_Width ] , & m_pSwitchTile [ ( y - o ) * m_Width ] , m_Width * sizeof ( CSwitchTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pSwitchTile [ ( y - o ) * m_Width ] , m_Width * sizeof ( CSwitchTile ) ) ;
}
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 + + )
if ( IsValidSwitchTile ( pLayer - > GetTile ( x , y ) . m_Index ) )
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 + + )
{
int fx = x + sx ;
int fy = y + sy ;
2019-03-26 18:15:24 +00:00
2010-09-30 21:31:19 +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 ;
if ( IsValidSwitchTile ( l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ) )
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
{
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_SwitchNum ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = m_pEditor - > m_SwitchDelay ;
}
else if ( l - > m_pSwitchTile [ y * l - > m_Width + x ] . m_Number )
{
2010-09-30 21:31:19 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = l - > m_pSwitchTile [ y * l - > m_Width + x ] . m_Number ;
2010-12-04 11:54:53 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = l - > m_pSwitchTile [ y * l - > m_Width + x ] . m_Delay ;
}
else
2010-09-30 21:31:19 +00:00
{
2015-08-22 18:41:46 +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
}
m_pSwitchTile [ fy * m_Width + fx ] . m_Type = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
2010-11-13 13:22:19 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Flags = l - > m_pTiles [ y * l - > m_Width + x ] . m_Flags ;
2010-09-30 21:31:19 +00:00
m_pTiles [ fy * m_Width + fx ] . m_Index = l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ;
2020-01-17 17:22:41 +00:00
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
{
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = 0 ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Type = 0 ;
2010-11-13 13:22:19 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Flags = 0 ;
2010-11-22 20:43:22 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = 0 ;
2010-09-30 21:31:19 +00:00
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
}
2011-01-25 09:34:14 +00:00
if ( l - > m_pTiles [ y * l - > m_Width + x ] . m_Index = = TILE_FREEZE )
{
m_pSwitchTile [ fy * m_Width + fx ] . m_Flags = 0 ;
}
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 )
{
m_pSwitchTile [ fy * m_Width + fx ] . m_Flags = 0 ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = 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
}
2019-03-21 21:50:22 +00:00
void CLayerSwitch : : BrushFlipX ( )
{
CLayerTiles : : BrushFlipX ( ) ;
for ( int y = 0 ; y < m_Height ; y + + )
for ( int x = 0 ; x < m_Width / 2 ; x + + )
{
CSwitchTile Tmp = m_pSwitchTile [ y * m_Width + x ] ;
m_pSwitchTile [ y * m_Width + x ] = m_pSwitchTile [ y * m_Width + m_Width - 1 - x ] ;
m_pSwitchTile [ y * m_Width + m_Width - 1 - x ] = Tmp ;
}
}
void CLayerSwitch : : BrushFlipY ( )
{
CLayerTiles : : BrushFlipY ( ) ;
for ( int y = 0 ; y < m_Height / 2 ; y + + )
for ( int x = 0 ; x < m_Width ; x + + )
{
CSwitchTile Tmp = m_pSwitchTile [ y * m_Width + x ] ;
m_pSwitchTile [ y * m_Width + x ] = m_pSwitchTile [ ( m_Height - 1 - y ) * m_Width + x ] ;
m_pSwitchTile [ ( m_Height - 1 - y ) * m_Width + x ] = Tmp ;
}
}
void CLayerSwitch : : BrushRotate ( float Amount )
{
int Rotation = ( round_to_int ( 360.0f * Amount / ( pi * 2 ) ) / 90 ) % 4 ; // 0=0°, 1=90°, 2=180°, 3=270°
if ( Rotation < 0 )
Rotation + = 4 ;
if ( Rotation = = 1 | | Rotation = = 3 )
{
// 90° rotation
CSwitchTile * pTempData1 = new CSwitchTile [ m_Width * m_Height ] ;
CTile * pTempData2 = new CTile [ m_Width * m_Height ] ;
mem_copy ( pTempData1 , m_pSwitchTile , m_Width * m_Height * sizeof ( CSwitchTile ) ) ;
mem_copy ( pTempData2 , m_pTiles , m_Width * m_Height * sizeof ( CTile ) ) ;
CSwitchTile * pDst1 = m_pSwitchTile ;
CTile * pDst2 = m_pTiles ;
for ( int x = 0 ; x < m_Width ; + + x )
for ( int y = m_Height - 1 ; y > = 0 ; - - y , + + pDst1 , + + pDst2 )
{
* 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 ) )
{
if ( pDst2 - > m_Flags & TILEFLAG_ROTATE )
pDst2 - > m_Flags ^ = ( TILEFLAG_HFLIP | TILEFLAG_VFLIP ) ;
pDst2 - > m_Flags ^ = TILEFLAG_ROTATE ;
}
2019-03-21 21:50:22 +00:00
}
int Temp = m_Width ;
m_Width = m_Height ;
m_Height = Temp ;
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 ) ;
CLayerSwitch * pLt = static_cast < CLayerSwitch * > ( pBrush ) ;
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
{
int fx = x + sx ;
int fy = y + sy ;
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 ;
if ( Empty | | ! 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
{
2011-02-13 05:35:13 +00:00
m_pTiles [ fy * m_Width + fx ] . m_Index = 0 ;
m_pSwitchTile [ fy * m_Width + fx ] . m_Type = 0 ;
2010-11-23 09:26:54 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Number = 0 ;
2014-03-19 09:26:38 +00:00
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
{
2011-02-13 05:35:13 +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 ;
2018-09-26 12:53:25 +00:00
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
{
2010-12-07 15:51:59 +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 ;
else
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 )
2015-04-21 02:57:20 +00:00
m_pSwitchTile [ fy * m_Width + fx ] . m_Delay = m_pEditor - > m_SwitchDelay ;
2010-12-07 15:51:59 +00:00
else
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
//------------------------------------------------------
CLayerTune : : CLayerTune ( int w , int h )
: CLayerTiles ( w , h )
{
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 ;
m_pTuneTile = new CTuneTile [ w * h ] ;
mem_zero ( m_pTuneTile , w * h * sizeof ( CTuneTile ) ) ;
}
CLayerTune : : ~ CLayerTune ( )
{
delete [ ] m_pTuneTile ;
}
void CLayerTune : : Resize ( int NewW , int NewH )
{
// resize Tune data
CTuneTile * pNewTuneData = new CTuneTile [ NewW * NewH ] ;
mem_zero ( pNewTuneData , NewW * NewH * sizeof ( CTuneTile ) ) ;
// copy old data
2019-04-26 19:36:49 +00:00
for ( int y = 0 ; y < minimum ( NewH , m_Height ) ; y + + )
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
delete [ ] m_pTuneTile ;
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 ) ;
2014-05-31 23:32:54 +00:00
int o = m_pEditor - > m_ShiftBy ;
2014-03-12 22:34:30 +00:00
switch ( Direction )
{
case 1 :
{
// left
for ( int y = 0 ; y < m_Height ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_move ( & m_pTuneTile [ y * m_Width ] , & m_pTuneTile [ y * m_Width + o ] , ( m_Width - o ) * sizeof ( CTuneTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTuneTile [ y * m_Width + ( m_Width - o ) ] , o * sizeof ( CTuneTile ) ) ;
}
2014-03-12 22:34:30 +00:00
}
break ;
case 2 :
{
// right
for ( int y = 0 ; y < m_Height ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_move ( & m_pTuneTile [ y * m_Width + o ] , & m_pTuneTile [ y * m_Width ] , ( m_Width - o ) * sizeof ( CTuneTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTuneTile [ y * m_Width ] , o * sizeof ( CTuneTile ) ) ;
}
2014-03-12 22:34:30 +00:00
}
break ;
case 4 :
{
// up
2014-05-31 23:32:54 +00:00
for ( int y = 0 ; y < m_Height - o ; + + y )
2014-06-01 11:16:25 +00:00
{
2014-05-31 23:32:54 +00:00
mem_copy ( & m_pTuneTile [ y * m_Width ] , & m_pTuneTile [ ( y + o ) * m_Width ] , m_Width * sizeof ( CTuneTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTuneTile [ ( y + o ) * m_Width ] , m_Width * sizeof ( CTuneTile ) ) ;
}
2014-03-12 22:34:30 +00:00
}
break ;
case 8 :
{
// down
2014-06-01 11:16:25 +00:00
for ( int y = m_Height - 1 ; y > = o ; - - y )
{
2014-05-31 23:32:54 +00:00
mem_copy ( & m_pTuneTile [ y * m_Width ] , & m_pTuneTile [ ( y - o ) * m_Width ] , m_Width * sizeof ( CTuneTile ) ) ;
2014-06-01 11:16:25 +00:00
mem_zero ( & m_pTuneTile [ ( y - o ) * m_Width ] , m_Width * sizeof ( CTuneTile ) ) ;
}
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 + + )
if ( IsValidTuneTile ( pLayer - > GetTile ( x , y ) . m_Index ) )
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 + + )
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
2014-03-12 22:34:30 +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 ;
if ( IsValidTuneTile ( l - > m_pTiles [ y * l - > m_Width + x ] . m_Index ) )
2014-03-12 22:34:30 +00:00
{
if ( m_pEditor - > m_TuningNum ! = l - > m_TuningNumber )
{
m_pTuneTile [ fy * m_Width + fx ] . m_Number = m_pEditor - > m_TuningNum ;
}
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 ;
else
{
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 ;
}
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 ;
}
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 ( ) ;
for ( int y = 0 ; y < m_Height ; y + + )
for ( int x = 0 ; x < m_Width / 2 ; x + + )
{
CTuneTile Tmp = m_pTuneTile [ y * m_Width + x ] ;
m_pTuneTile [ y * m_Width + x ] = m_pTuneTile [ y * m_Width + m_Width - 1 - x ] ;
m_pTuneTile [ y * m_Width + m_Width - 1 - x ] = Tmp ;
}
}
void CLayerTune : : BrushFlipY ( )
{
CLayerTiles : : BrushFlipY ( ) ;
for ( int y = 0 ; y < m_Height / 2 ; y + + )
for ( int x = 0 ; x < m_Width ; x + + )
{
CTuneTile Tmp = m_pTuneTile [ y * m_Width + x ] ;
m_pTuneTile [ y * m_Width + x ] = m_pTuneTile [ ( m_Height - 1 - y ) * m_Width + x ] ;
m_pTuneTile [ ( m_Height - 1 - y ) * m_Width + x ] = Tmp ;
}
}
void CLayerTune : : BrushRotate ( float Amount )
{
2014-04-22 21:46:55 +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 )
Rotation + = 4 ;
if ( Rotation = = 1 | | Rotation = = 3 )
{
2014-03-23 16:42:00 +00:00
// 90° rotation
2014-03-12 22:34:30 +00:00
CTuneTile * pTempData1 = new CTuneTile [ m_Width * m_Height ] ;
CTile * pTempData2 = new CTile [ m_Width * m_Height ] ;
mem_copy ( pTempData1 , m_pTuneTile , m_Width * m_Height * sizeof ( CTuneTile ) ) ;
mem_copy ( pTempData2 , m_pTiles , m_Width * m_Height * sizeof ( CTile ) ) ;
CTuneTile * pDst1 = m_pTuneTile ;
CTile * pDst2 = m_pTiles ;
for ( int x = 0 ; x < m_Width ; + + x )
for ( int y = m_Height - 1 ; y > = 0 ; - - y , + + pDst1 , + + pDst2 )
{
* pDst1 = pTempData1 [ y * m_Width + x ] ;
* pDst2 = pTempData2 [ y * m_Width + x ] ;
}
int Temp = m_Width ;
m_Width = m_Height ;
m_Height = Temp ;
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 <=
int sx = ConvertX ( Rect . x ) ;
int sy = ConvertY ( Rect . y ) ;
int w = ConvertX ( Rect . w ) ;
int h = ConvertY ( Rect . h ) ;
CLayerTune * pLt = static_cast < CLayerTune * > ( pBrush ) ;
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-12 22:34:30 +00:00
for ( int y = 0 ; y < h ; y + + )
{
for ( int x = 0 ; x < w ; x + + )
{
int fx = x + sx ;
int fy = y + sy ;
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 ;
if ( Empty | | ! 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
2014-03-12 22:34:30 +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 ) ] ;
2018-09-26 12:53:25 +00:00
if ( pLt - > m_Tune & & m_pTiles [ fy * m_Width + fx ] . m_Index > 0 )
2014-03-12 22:34:30 +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 ;
2018-09-26 12:53:25 +00:00
m_pTuneTile [ fy * m_Width + fx ] . m_Type = m_pTiles [ fy * m_Width + fx ] . m_Index ;
2014-03-12 22:34:30 +00:00
}
}
}
}
2018-10-04 13:26:41 +00:00
FlagModified ( sx , sy , w , h ) ;
2014-03-23 16:42:00 +00:00
}