Don't rotate static game tiles and fix switch rotation

Should be handy for mapping.
Can be disabled by activating unused tiles (don't think it's worth a separate toggle and if you want to do it, you're doing something unusal)
This commit is contained in:
12pm 2019-03-21 22:50:22 +01:00
parent 4c7b6f949e
commit dff702bd2c
4 changed files with 106 additions and 5 deletions

View file

@ -1135,6 +1135,9 @@ public:
virtual void Resize(int NewW, int NewH); virtual void Resize(int NewW, int NewH);
virtual void Shift(int Direction); virtual void Shift(int Direction);
virtual void BrushDraw(CLayer *pBrush, float wx, float wy); virtual void BrushDraw(CLayer *pBrush, float wx, float wy);
virtual void BrushFlipX();
virtual void BrushFlipY();
virtual void BrushRotate(float Amount);
virtual void FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect); virtual void FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect);
}; };

View file

@ -445,8 +445,15 @@ void CLayerTiles::BrushFlipX()
m_pTiles[y*m_Width+m_Width-1-x] = Tmp; m_pTiles[y*m_Width+m_Width-1-x] = Tmp;
} }
if(m_Tele || m_Switch || m_Speedup || m_Tune)
return;
bool Rotate = !(m_Game || m_Front) || m_pEditor->m_AllowPlaceUnusedTiles;
for(int y = 0; y < m_Height; y++) for(int y = 0; y < m_Height; y++)
for(int x = 0; x < m_Width; x++) for(int x = 0; x < m_Width; x++)
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; m_pTiles[y*m_Width+x].m_Flags ^= m_pTiles[y*m_Width+x].m_Flags&TILEFLAG_ROTATE ? TILEFLAG_HFLIP : TILEFLAG_VFLIP;
} }
@ -460,8 +467,15 @@ void CLayerTiles::BrushFlipY()
m_pTiles[(m_Height-1-y)*m_Width+x] = Tmp; m_pTiles[(m_Height-1-y)*m_Width+x] = Tmp;
} }
if(m_Tele || m_Switch || m_Speedup || m_Tune)
return;
bool Rotate = !(m_Game || m_Front) || m_pEditor->m_AllowPlaceUnusedTiles;
for(int y = 0; y < m_Height; y++) for(int y = 0; y < m_Height; y++)
for(int x = 0; x < m_Width; x++) for(int x = 0; x < m_Width; x++)
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; m_pTiles[y*m_Width+x].m_Flags ^= m_pTiles[y*m_Width+x].m_Flags&TILEFLAG_ROTATE ? TILEFLAG_VFLIP : TILEFLAG_HFLIP;
} }
@ -477,14 +491,20 @@ void CLayerTiles::BrushRotate(float Amount)
CTile *pTempData = new CTile[m_Width*m_Height]; CTile *pTempData = new CTile[m_Width*m_Height];
mem_copy(pTempData, m_pTiles, m_Width*m_Height*sizeof(CTile)); mem_copy(pTempData, m_pTiles, m_Width*m_Height*sizeof(CTile));
CTile *pDst = m_pTiles; CTile *pDst = m_pTiles;
bool Rotate = !(m_Game || m_Front) || m_pEditor->m_AllowPlaceUnusedTiles;
for(int x = 0; x < m_Width; ++x) for(int x = 0; x < m_Width; ++x)
for(int y = m_Height-1; y >= 0; --y, ++pDst) for(int y = m_Height-1; y >= 0; --y, ++pDst)
{ {
*pDst = pTempData[y*m_Width+x]; *pDst = pTempData[y*m_Width+x];
if(!Rotate && !IsRotatableTile(pDst->m_Index))
pDst->m_Flags = 0;
else
{
if(pDst->m_Flags&TILEFLAG_ROTATE) if(pDst->m_Flags&TILEFLAG_ROTATE)
pDst->m_Flags ^= (TILEFLAG_HFLIP|TILEFLAG_VFLIP); pDst->m_Flags ^= (TILEFLAG_HFLIP|TILEFLAG_VFLIP);
pDst->m_Flags ^= TILEFLAG_ROTATE; pDst->m_Flags ^= TILEFLAG_ROTATE;
} }
}
int Temp = m_Width; int Temp = m_Width;
m_Width = m_Height; m_Width = m_Height;
@ -1654,6 +1674,68 @@ void CLayerSwitch::BrushDraw(CLayer *pBrush, float wx, float wy)
FlagModified(sx, sy, l->m_Width, l->m_Height); FlagModified(sx, sy, l->m_Width, l->m_Height);
} }
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];
}
int Temp = m_Width;
m_Width = m_Height;
m_Height = Temp;
delete[] pTempData1;
delete[] pTempData2;
}
if(Rotation == 2 || Rotation == 3)
{
BrushFlipX();
BrushFlipY();
}
}
void CLayerSwitch::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect) void CLayerSwitch::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
{ {
if(m_Readonly || (!Empty && pBrush->m_Type != LAYERTYPE_TILES)) if(m_Readonly || (!Empty && pBrush->m_Type != LAYERTYPE_TILES))

View file

@ -91,3 +91,18 @@ bool IsValidEntity(int Index)
|| Index == ENTITY_DOOR || Index == ENTITY_DOOR
); );
} }
bool IsRotatableTile(int Index)
{
return (
Index == TILE_STOP
|| Index == TILE_STOPS
|| Index == TILE_CP
|| Index == TILE_CP_F
|| Index == TILE_THROUGH_DIR
|| Index == TILE_ENTITIES_OFF_1
|| Index == TILE_ENTITIES_OFF_2
|| Index - ENTITY_OFFSET == ENTITY_CRAZY_SHOTGUN_EX
|| Index - ENTITY_OFFSET == ENTITY_CRAZY_SHOTGUN
);
}

View file

@ -472,5 +472,6 @@ bool IsValidTeleTile(int Index);
bool IsValidSpeedupTile(int Index); bool IsValidSpeedupTile(int Index);
bool IsValidSwitchTile(int Index); bool IsValidSwitchTile(int Index);
bool IsValidEntity(int Index); bool IsValidEntity(int Index);
bool IsRotatableTile(int Index);
#endif #endif