ddnet/src/game/editor/ed_layer_tiles.cpp

839 lines
24 KiB
C++
Raw Normal View History

2010-05-29 07:25:38 +00:00
#include <base/math.h>
2010-05-29 07:25:38 +00:00
#include <engine/graphics.h>
#include <engine/textrender.h>
#include <engine/input.h>
#include <engine/keys.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>
#include "ed_editor.h"
2008-01-12 12:27:55 +00:00
#include <game/localization.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;
m_pTypeName = "Tiles";
m_Width = w;
m_Height = h;
m_Image = -1;
m_TexId = -1;
m_Game = 0;
m_Tele = 0;
m_Speedup = 0;
m_Front = 0;
m_Switch = 0;
2008-01-12 12:27:55 +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
}
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++)
m_pTiles[y*m_Width+x].m_Flags &= TILEFLAG_VFLIP|TILEFLAG_HFLIP;
2008-03-29 11:44:03 +00:00
2010-05-29 07:25:38 +00:00
if(m_Image != -1)
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
}
2010-05-29 07:25:38 +00:00
void CLayerTiles::Render()
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())
m_TexId = m_pEditor->m_Map.m_lImages[m_Image]->m_TexId;
Graphics()->TextureSet(m_TexId);
m_pEditor->RenderTools()->RenderTilemap(m_pTiles, m_Width, m_Height, 32.0f, vec4(1,1,1,1), LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT);
if(m_Tele)
m_pEditor->RenderTools()->RenderTelemap(((CLayerTele*)this)->m_pTeleTile, m_Width, m_Height, 32.0f);
if(m_Speedup)
m_pEditor->RenderTools()->RenderSpeedupmap(((CLayerSpeedup*)this)->m_pSpeedupTile, m_Width, m_Height, 32.0f);
if(m_Switch)
m_pEditor->RenderTools()->RenderSwitchmap(((CLayerSwitch*)this)->m_pSwitchTile, 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
}
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
}
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;
2008-01-12 12:27:55 +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
}
2010-05-29 07:25:38 +00:00
void CLayerTiles::BrushSelecting(CUIRect Rect)
2008-01-12 12:27:55 +00:00
{
2009-10-27 14:38:53 +00:00
Graphics()->TextureSet(-1);
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));
TextRender()->Text(0, Rect.x+3.0f, Rect.y+3.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);
2008-01-12 12:27:55 +00:00
if(!r.w || !r.h)
return 0;
// create new layers
if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pTeleLayer)
{
CLayerTele *pGrabbed = new CLayerTele(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexId = m_TexId;
pGrabbed->m_Image = m_Image;
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] = m_pTiles[(r.y+y)*m_Width+(r.x+x)];
// copy the tele data
if(!m_pEditor->Input()->KeyPressed(KEY_SPACE))
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)];
}
else if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pSpeedupLayer)
{
CLayerSpeedup *pGrabbed = new CLayerSpeedup(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexId = m_TexId;
pGrabbed->m_Image = m_Image;
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] = m_pTiles[(r.y+y)*m_Width+(r.x+x)];
// copy the speedup data
if(!m_pEditor->Input()->KeyPressed(KEY_SPACE))
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)];
}
else if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pSwitchLayer)
{
CLayerSwitch *pGrabbed = new CLayerSwitch(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexId = m_TexId;
pGrabbed->m_Image = m_Image;
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] = m_pTiles[(r.y+y)*m_Width+(r.x+x)];
// copy the switch data
if(!m_pEditor->Input()->KeyPressed(KEY_SPACE))
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)];
}
else
{
CLayerTiles *pGrabbed = new CLayerTiles(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexId = m_TexId;
pGrabbed->m_Image = m_Image;
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] = m_pTiles[(r.y+y)*m_Width+(r.x+x)];
}
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
{
2010-05-29 07:25:38 +00:00
if(m_Readonly)
return;
int sx = ConvertX(Rect.x);
int sy = ConvertY(Rect.y);
int w = ConvertX(Rect.w);
int h = ConvertY(Rect.h);
CLayerTiles *pLt = static_cast<CLayerTiles*>(pBrush);
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;
if(Empty)
m_pTiles[fy*m_Width+fx].m_Index = 1;
else
m_pTiles[fy*m_Width+fx] = pLt->m_pTiles[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)];
}
}
}
void CLayerTiles::BrushDraw(CLayer *pBrush, float wx, float wy)
{
if(m_Readonly)
2008-03-20 23:59:41 +00:00
return;
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);
2008-01-12 12:27:55 +00:00
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;
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;
// dont allow tele in and out tiles... same with speedup tile in game layer
if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pGameLayer && (l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_TRIGGER + ENTITY_OFFSET)|| l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_DOOR + ENTITY_OFFSET)))
continue;
2010-05-29 07:25:38 +00:00
m_pTiles[fy*m_Width+fx] = l->m_pTiles[y*l->m_Width+x];
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
}
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 ^= 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
}
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 ^= TILEFLAG_HFLIP;
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
// copy old data
2010-05-29 07:25:38 +00:00
for(int y = 0; y < min(NewH, m_Height); y++)
mem_copy(&pNewData[y*NewW], &m_pTiles[y*m_Width], min(m_Width, NewW)*sizeof(CTile));
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;
// 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);
2008-01-12 12:27:55 +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;
pToolBox->HSplitBottom(12.0f, pToolBox, &Button);
bool InGameGroup = !find_linear(m_pEditor->m_Map.m_pGameGroup->m_lLayers.all(), this).empty();
if(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)
2010-05-29 07:25:38 +00:00
InGameGroup = false;
static int s_ColclButton = 0;
if(m_pEditor->DoButton_Editor(&s_ColclButton, Localize("Clear collision"), InGameGroup?0:-1, &Button, 0, Localize("Removes collision from this layer")))
2008-09-07 08:30:49 +00:00
{
2010-05-29 07:25:38 +00:00
CLayerTiles *gl = m_pEditor->m_Map.m_pGameLayer;
int w = min(gl->m_Width, m_Width);
int h = min(gl->m_Height, m_Height);
2008-09-07 08:30:49 +00:00
for(int y = 0; y < h; y++)
for(int x = 0; x < w; x++)
{
2010-05-29 07:25:38 +00:00
if(gl->m_pTiles[y*gl->m_Width+x].m_Index <= TILE_SOLID)
if(m_pTiles[y*m_Width+x].m_Index)
gl->m_pTiles[y*gl->m_Width+x].m_Index = TILE_AIR;
2008-09-07 08:30:49 +00:00
}
return 1;
}
2010-05-29 07:25:38 +00:00
static int s_ColButton = 0;
pToolBox->HSplitBottom(5.0f, pToolBox, &Button);
pToolBox->HSplitBottom(12.0f, pToolBox, &Button);
if(m_pEditor->DoButton_Editor(&s_ColButton, Localize("Make collision"), InGameGroup?0:-1, &Button, 0, Localize("Constructs collision from this layer")))
2008-01-13 22:03:32 +00:00
{
2010-05-29 07:25:38 +00:00
CLayerTiles *gl = m_pEditor->m_Map.m_pGameLayer;
int w = min(gl->m_Width, m_Width);
int h = min(gl->m_Height, m_Height);
2008-01-13 22:03:32 +00:00
for(int y = 0; y < h; y++)
for(int x = 0; x < w; x++)
{
2010-05-29 07:25:38 +00:00
if(gl->m_pTiles[y*gl->m_Width+x].m_Index <= TILE_SOLID)
gl->m_pTiles[y*gl->m_Width+x].m_Index = m_pTiles[y*m_Width+x].m_Index?TILE_SOLID:TILE_AIR;
2008-01-13 22:03:32 +00:00
}
return 1;
}
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,
2008-03-21 00:13:55 +00:00
PROP_IMAGE,
2008-01-12 12:27:55 +00:00
NUM_PROPS,
};
2010-05-29 07:25:38 +00:00
CProperty aProps[] = {
{Localize("Width"), m_Width, PROPTYPE_INT_SCROLL, 1, 1000000000},
{Localize("Height"), m_Height, PROPTYPE_INT_SCROLL, 1, 1000000000},
{Localize("Image"), m_Image, PROPTYPE_IMAGE, 0, 0},
2008-01-12 12:27:55 +00:00
{0},
};
if(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) // remove the image from the selection if this is the game/tele/speedup/front/switch layer
2010-05-29 07:25:38 +00:00
aProps[2].m_pName = 0;
2008-03-20 23:59:41 +00:00
2010-05-29 07:25:38 +00:00
static int s_aIds[NUM_PROPS] = {0};
int NewVal = 0;
int Prop = m_pEditor->DoProperties(pToolBox, aProps, s_aIds, &NewVal);
2008-01-12 12:27:55 +00:00
2010-05-29 07:25:38 +00:00
if(Prop == PROP_WIDTH && NewVal > 1)
Resize(NewVal, m_Height);
else if(Prop == PROP_HEIGHT && NewVal > 1)
Resize(m_Width, NewVal);
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
{
2010-05-29 07:25:38 +00:00
m_TexId = -1;
m_Image = -1;
2008-09-07 08:30:49 +00:00
}
else
2010-05-29 07:25:38 +00:00
m_Image = NewVal%m_pEditor->m_Map.m_lImages.size();
2008-09-07 08:30:49 +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
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
{
}
CLayerTele::CLayerTele(int w, int h)
: CLayerTiles(w, h)
{
m_pTypeName = "Tele";
m_Tele = 1;
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));
// copy old data
for(int y = 0; y < min(NewH, m_Height); y++)
mem_copy(&pNewTeleData[y*NewW], &m_pTeleTile[y*m_Width], min(m_Width, NewW)*sizeof(CTeleTile));
// replace old
delete [] m_pTeleTile;
m_pTeleTile = pNewTeleData;
// 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 CLayerTele::BrushDraw(CLayer *pBrush, float wx, float wy)
{
CLayerTele *l = (CLayerTele *)pBrush;
int sx = ConvertX(wx);
int sy = ConvertY(wy);
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;
if(fx<0 || fx >= m_Width || fy < 0 || fy >= m_Height)
continue;
if(l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT)
{
if(l->m_pTeleTile[y*l->m_Width+x].m_Number)
m_pTeleTile[fy*m_Width+fx].m_Number = l->m_pTeleTile[y*l->m_Width+x].m_Number;
else
{
if(!m_pEditor->m_TeleNum)
{
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
m_pTeleTile[fy*m_Width+fx].m_Number = m_pEditor->m_TeleNum;
}
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;
}
}
}
void CLayerTele::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
{
if(m_Readonly)
return;
int sx = ConvertX(Rect.x);
int sy = ConvertY(Rect.y);
int w = ConvertX(Rect.w);
int h = ConvertY(Rect.h);
CLayerTele *pLt = static_cast<CLayerTele*>(pBrush);
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;
if(Empty)
{
m_pTiles[fy*m_Width+fx].m_Index = 0;
m_pTeleTile[fy*m_Width+fx].m_Number = 0;
}
else
{
m_pTiles[fy*m_Width+fx] = pLt->m_pTiles[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)];
if(!pLt->m_pTeleTile[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)].m_Number && m_pEditor->m_TeleNum && m_pTiles[fy*m_Width+fx].m_Index > 0)
m_pTeleTile[fy*m_Width+fx].m_Number = m_pEditor->m_TeleNum;
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;
}
}
}
}
CLayerSpeedup::CLayerSpeedup(int w, int h)
: CLayerTiles(w, h)
{
m_pTypeName = "Speedup";
m_Speedup = 1;
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));
// copy old data
for(int y = 0; y < min(NewH, m_Height); y++)
mem_copy(&pNewSpeedupData[y*NewW], &m_pSpeedupTile[y*m_Width], min(m_Width, NewW)*sizeof(CSpeedupTile));
// replace old
delete [] m_pSpeedupTile;
m_pSpeedupTile = pNewSpeedupData;
// 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 CLayerSpeedup::BrushDraw(CLayer *pBrush, float wx, float wy)
{
CLayerSpeedup *l = (CLayerSpeedup *)pBrush;
int sx = ConvertX(wx);
int sy = ConvertY(wy);
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;
if(fx<0 || fx >= m_Width || fy < 0 || fy >= m_Height)
continue;
if(l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST)
{
if(l->m_pSpeedupTile[y*l->m_Width+x].m_Force || l->m_pSpeedupTile[y*l->m_Width+x].m_Angle)
{
m_pSpeedupTile[fy*m_Width+fx].m_Force = l->m_pSpeedupTile[y*l->m_Width+x].m_Force;
m_pSpeedupTile[fy*m_Width+fx].m_Angle = l->m_pSpeedupTile[y*l->m_Width+x].m_Angle;
m_pTiles[fy*m_Width+fx].m_Index = l->m_pTiles[y*l->m_Width+x].m_Index;
}
else if(m_pEditor->m_SpeedupForce)
{
m_pSpeedupTile[fy*m_Width+fx].m_Force = m_pEditor->m_SpeedupForce;
m_pSpeedupTile[fy*m_Width+fx].m_Angle = m_pEditor->m_SpeedupAngle;
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_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_Angle = 0;
m_pTiles[fy*m_Width+fx].m_Index = 0;
}
}
}
void CLayerSpeedup::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
{
if(m_Readonly)
return;
int sx = ConvertX(Rect.x);
int sy = ConvertY(Rect.y);
int w = ConvertX(Rect.w);
int h = ConvertY(Rect.h);
CLayerSpeedup *pLt = static_cast<CLayerSpeedup*>(pBrush);
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;
if(Empty)
{
m_pTiles[fy*m_Width+fx].m_Index = 0;
m_pSpeedupTile[fy*m_Width+fx].m_Force = 0;
m_pSpeedupTile[fy*m_Width+fx].m_Angle = 0;
}
else
{
m_pTiles[fy*m_Width+fx] = pLt->m_pTiles[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)];
if(!pLt->m_pSpeedupTile[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)].m_Force && m_pEditor->m_SpeedupForce && m_pTiles[fy*m_Width+fx].m_Index > 0)
{
m_pSpeedupTile[fy*m_Width+fx].m_Force = m_pEditor->m_SpeedupForce;
m_pSpeedupTile[fy*m_Width+fx].m_Angle = m_pEditor->m_SpeedupAngle;
}
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;
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;
}
}
}
}
}
CLayerFront::CLayerFront(int w, int h)
: CLayerTiles(w, h)
{
m_pTypeName = "Front";
m_Front = 1;
}
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);
}
void CLayerFront::BrushDraw(CLayer *pBrush, float wx, float wy)
{
if(m_Readonly)
return;
//
CLayerTiles *l = (CLayerTiles *)pBrush;
int sx = ConvertX(wx);
int sy = ConvertY(wy);
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;
if(fx<0 || fx >= m_Width || fy < 0 || fy >= m_Height)
continue;
// dont allow tele in and out tiles... same with speedup tile in front
if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pFrontLayer && (l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_TRIGGER + ENTITY_OFFSET)|| l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_DOOR + ENTITY_OFFSET)))
continue;
m_pTiles[fy*m_Width+fx] = l->m_pTiles[y*l->m_Width+x];
}
}
CLayerSwitch::CLayerSwitch(int w, int h)
: CLayerTiles(w, h)
{
m_pTypeName = "Switch";
m_Switch = 1;
m_pSwitchTile = new CTeleTile[w*h];
mem_zero(m_pSwitchTile, w*h*sizeof(CTeleTile));
}
CLayerSwitch::~CLayerSwitch()
{
delete[] m_pSwitchTile;
}
void CLayerSwitch::Resize(int NewW, int NewH)
{
// resize switch data
CTeleTile *pNewSwitchData = new CTeleTile[NewW*NewH];
mem_zero(pNewSwitchData, NewW*NewH*sizeof(CTeleTile));
// copy old data
for(int y = 0; y < min(NewH, m_Height); y++)
mem_copy(&pNewSwitchData[y*NewW], &m_pSwitchTile[y*m_Width], min(m_Width, NewW)*sizeof(CTeleTile));
// 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);
}
void CLayerSwitch::BrushDraw(CLayer *pBrush, float wx, float wy)
{
CLayerSwitch *l = (CLayerSwitch *)pBrush;
int sx = ConvertX(wx);
int sy = ConvertY(wy);
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;
if(fx<0 || fx >= m_Width || fy < 0 || fy >= m_Height)
continue;
if(l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_DOOR + ENTITY_OFFSET) || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_TRIGGER + ENTITY_OFFSET) || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_LASER_LONG + ENTITY_OFFSET) || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_LASER_MIDDLE + ENTITY_OFFSET) || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_LASER_SHORT + ENTITY_OFFSET))
{
if(l->m_pSwitchTile[y*l->m_Width+x].m_Number)
m_pSwitchTile[fy*m_Width+fx].m_Number = l->m_pSwitchTile[y*l->m_Width+x].m_Number;
else
{
if(!m_pEditor->m_SwitchNum)
{
m_pSwitchTile[fy*m_Width+fx].m_Number = 0;
m_pSwitchTile[fy*m_Width+fx].m_Type = 0;
m_pTiles[fy*m_Width+fx].m_Index = 0;
continue;
}
else
m_pSwitchTile[fy*m_Width+fx].m_Number = m_pEditor->m_SwitchNum;
}
m_pSwitchTile[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_pSwitchTile[fy*m_Width+fx].m_Number = 0;
m_pSwitchTile[fy*m_Width+fx].m_Type = 0;
m_pTiles[fy*m_Width+fx].m_Index = 0;
}
}
}
void CLayerSwitch::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
{
if(m_Readonly)
return;
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);
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;
if(Empty)
{
m_pTiles[fy*m_Width+fx].m_Index = 0;
m_pSwitchTile[fy*m_Width+fx].m_Number = 0;
}
else
{
m_pTiles[fy*m_Width+fx] = pLt->m_pTiles[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)];
if(!pLt->m_pSwitchTile[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)].m_Number && m_pEditor->m_SwitchNum && m_pTiles[fy*m_Width+fx].m_Index > 0)
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;
}
}
}
}