mirror of
https://github.com/blupi-games/planetblupi
synced 2024-12-30 10:15:36 +01:00
978 lines
18 KiB
C++
978 lines
18 KiB
C++
// Arrange.cpp
|
|
//
|
|
|
|
#include "DECOR.H"
|
|
#include "MISC.H"
|
|
|
|
// Cette table indique les quarts de cases contenant de
|
|
// l'eau lorsque la valeur est à un.
|
|
// 0 1
|
|
// 2 3
|
|
static char tableSee[14*4] =
|
|
{
|
|
0,0,0,0, // 1
|
|
0,1,0,1, // 2
|
|
0,0,1,1, // 3
|
|
1,0,1,0, // 4
|
|
1,1,0,0, // 5
|
|
0,0,0,1, // 6
|
|
0,0,1,0, // 7
|
|
1,0,0,0, // 8
|
|
0,1,0,0, // 9
|
|
0,1,1,1, // 10
|
|
1,0,1,1, // 11
|
|
1,1,1,0, // 12
|
|
1,1,0,1, // 13
|
|
1,1,1,1, // 14
|
|
};
|
|
|
|
// Cette table indique les quarts de cases contenant de
|
|
// la mousse ou de la terre lorsque la valeur est à un.
|
|
// 0 1
|
|
// 2 3
|
|
static char tableDark[13*4] =
|
|
{
|
|
1,1,1,1, // 20
|
|
0,1,0,1, // 21
|
|
0,0,1,1, // 22
|
|
1,0,1,0, // 23
|
|
1,1,0,0, // 24
|
|
0,0,0,1, // 25
|
|
0,0,1,0, // 26
|
|
1,0,0,0, // 27
|
|
0,1,0,0, // 28
|
|
1,1,1,0, // 29
|
|
1,1,0,1, // 30
|
|
0,1,1,1, // 31
|
|
1,0,1,1, // 32
|
|
};
|
|
|
|
// Retourne les bits contenant de l'eau.
|
|
|
|
bool CDecor::GetSeeBits(POINT cel, char *pBits, int index)
|
|
{
|
|
int icon;
|
|
|
|
pBits[0] = 0;
|
|
pBits[1] = 0;
|
|
pBits[2] = 0;
|
|
pBits[3] = 0;
|
|
|
|
if ( cel.x < 0 || cel.x >= MAXCELX ||
|
|
cel.y < 0 || cel.y >= MAXCELY ) return false;
|
|
|
|
icon = m_decor[cel.x/2][cel.y/2].floorIcon;
|
|
|
|
if ( index == 0 ) // eau ?
|
|
{
|
|
if ( icon < 1 || icon > 14 ) return true;
|
|
icon -= 1;
|
|
pBits[0] = tableSee[icon*4+0];
|
|
pBits[1] = tableSee[icon*4+1];
|
|
pBits[2] = tableSee[icon*4+2];
|
|
pBits[3] = tableSee[icon*4+3];
|
|
}
|
|
|
|
if ( index == 1 ) // mousse ?
|
|
{
|
|
if ( icon >= 2 && icon <= 14 ) return false; // eau ?
|
|
if ( icon == 66 || icon == 79 ) // mousse spéciale ?
|
|
{
|
|
pBits[0] = 1;
|
|
pBits[1] = 1;
|
|
pBits[2] = 1;
|
|
pBits[3] = 1;
|
|
return true;
|
|
}
|
|
if ( icon < 20 || icon > 32 ) return true;
|
|
icon -= 20;
|
|
pBits[0] = tableDark[icon*4+0];
|
|
pBits[1] = tableDark[icon*4+1];
|
|
pBits[2] = tableDark[icon*4+2];
|
|
pBits[3] = tableDark[icon*4+3];
|
|
}
|
|
|
|
if ( index == 2 ) // terre ?
|
|
{
|
|
if ( icon >= 2 && icon <= 14 ) return false; // eau ?
|
|
if ( (icon >= 46 && icon <= 48) || // terre spéciale ?
|
|
icon == 71 ) // terre à fer ?
|
|
{
|
|
pBits[0] = 1;
|
|
pBits[1] = 1;
|
|
pBits[2] = 1;
|
|
pBits[3] = 1;
|
|
return true;
|
|
}
|
|
if ( icon < 33 || icon > 45 ) return true;
|
|
icon -= 33;
|
|
pBits[0] = tableDark[icon*4+0];
|
|
pBits[1] = tableDark[icon*4+1];
|
|
pBits[2] = tableDark[icon*4+2];
|
|
pBits[3] = tableDark[icon*4+3];
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CopyBits(char *pDst, char *pSrc)
|
|
{
|
|
for ( int i=0 ; i<4 ; i++ )
|
|
{
|
|
*pDst++ = *pSrc++;
|
|
}
|
|
}
|
|
|
|
bool ChangeBits(char *pDst, char *pSrc)
|
|
{
|
|
for ( int i=0 ; i<4 ; i++ )
|
|
{
|
|
if ( *pDst++ != *pSrc++ ) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Retourne l'icône correspondant aux bits d'eaux.
|
|
|
|
int CDecor::GetSeeIcon(char *pBits, int index)
|
|
{
|
|
int i;
|
|
|
|
if ( index == 0 ) // eau ?
|
|
{
|
|
for ( i=0 ; i<14 ; i++ )
|
|
{
|
|
if ( tableSee[i*4+0] == pBits[0] &&
|
|
tableSee[i*4+1] == pBits[1] &&
|
|
tableSee[i*4+2] == pBits[2] &&
|
|
tableSee[i*4+3] == pBits[3] ) return i+1;
|
|
}
|
|
}
|
|
|
|
if ( index == 1 ) // mousse ?
|
|
{
|
|
for ( i=0 ; i<13 ; i++ )
|
|
{
|
|
if ( tableDark[i*4+0] == pBits[0] &&
|
|
tableDark[i*4+1] == pBits[1] &&
|
|
tableDark[i*4+2] == pBits[2] &&
|
|
tableDark[i*4+3] == pBits[3] ) return i+20;
|
|
}
|
|
}
|
|
|
|
if ( index == 2 ) // terre ?
|
|
{
|
|
for ( i=0 ; i<13 ; i++ )
|
|
{
|
|
if ( tableDark[i*4+0] == pBits[0] &&
|
|
tableDark[i*4+1] == pBits[1] &&
|
|
tableDark[i*4+2] == pBits[2] &&
|
|
tableDark[i*4+3] == pBits[3] ) return i+33;
|
|
}
|
|
}
|
|
|
|
if ( pBits[0] == 0 &&
|
|
pBits[1] == 0 &&
|
|
pBits[2] == 0 &&
|
|
pBits[3] == 0 ) return 1; // herbe
|
|
|
|
return -1;
|
|
}
|
|
|
|
// Arrange le sol après une modification.
|
|
|
|
void CDecor::ArrangeFloor(POINT cel)
|
|
{
|
|
POINT test;
|
|
int max, index, icon;
|
|
char here[4], bits[4], init[4];
|
|
bool bModif = false;
|
|
|
|
icon = m_decor[cel.x/2][cel.y/2].floorIcon;
|
|
|
|
if ( icon >= 59 && icon <= 64 ) return; // pont ?
|
|
|
|
max = 3;
|
|
if ( icon >= 15 && icon <= 18 ) // dalle spéciale ?
|
|
{
|
|
max = 1; // s'occupe que de l'eau !
|
|
}
|
|
|
|
for ( index=0 ; index<max ; index++ )
|
|
{
|
|
if ( !GetSeeBits(cel, here, index) ) continue;
|
|
|
|
test.x = cel.x -2; // en bas à gauche
|
|
test.y = cel.y +2;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
if ( bits[2] == here[2] &&
|
|
bits[0] != here[2] &&
|
|
bits[1] != here[2] &&
|
|
bits[3] != here[2] )
|
|
{
|
|
here[2] = bits[1];
|
|
bModif = true;
|
|
}
|
|
}
|
|
|
|
test.x = cel.x -2; // en haut à gauche
|
|
test.y = cel.y -2;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
if ( bits[0] == here[0] &&
|
|
bits[1] != here[0] &&
|
|
bits[2] != here[0] &&
|
|
bits[3] != here[0] )
|
|
{
|
|
here[0] = bits[3];
|
|
bModif = true;
|
|
}
|
|
}
|
|
|
|
test.x = cel.x +2; // en haut à droite
|
|
test.y = cel.y -2;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
if ( bits[1] == here[1] &&
|
|
bits[0] != here[1] &&
|
|
bits[2] != here[1] &&
|
|
bits[3] != here[1] )
|
|
{
|
|
here[1] = bits[2];
|
|
bModif = true;
|
|
}
|
|
}
|
|
|
|
test.x = cel.x +2; // en bas à droite
|
|
test.y = cel.y +2;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
if ( bits[3] == here[3] &&
|
|
bits[0] != here[3] &&
|
|
bits[1] != here[3] &&
|
|
bits[2] != here[3] )
|
|
{
|
|
here[3] = bits[0];
|
|
bModif = true;
|
|
}
|
|
}
|
|
|
|
if ( bModif )
|
|
{
|
|
icon = GetSeeIcon(here, index);
|
|
if ( icon != -1 ) m_decor[cel.x/2][cel.y/2].floorIcon = icon;
|
|
}
|
|
|
|
|
|
test.x = cel.x -2; // à gauche
|
|
test.y = cel.y;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
CopyBits(init, bits);
|
|
bits[1] = here[0]?1:0;
|
|
bits[3] = here[2]?1:0;
|
|
icon = GetSeeIcon(bits, index);
|
|
if ( ChangeBits(init, bits) && icon != -1 )
|
|
{
|
|
m_decor[test.x/2][test.y/2].floorIcon = icon;
|
|
}
|
|
}
|
|
|
|
test.x = cel.x -2; // en haut à gauche
|
|
test.y = cel.y -2;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
CopyBits(init, bits);
|
|
bits[3] = here[0]?1:0;
|
|
icon = GetSeeIcon(bits, index);
|
|
if ( ChangeBits(init, bits) && icon != -1 )
|
|
{
|
|
m_decor[test.x/2][test.y/2].floorIcon = icon;
|
|
}
|
|
}
|
|
|
|
test.x = cel.x; // en haut
|
|
test.y = cel.y -2;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
CopyBits(init, bits);
|
|
bits[2] = here[0]?1:0;
|
|
bits[3] = here[1]?1:0;
|
|
icon = GetSeeIcon(bits, index);
|
|
if ( ChangeBits(init, bits) && icon != -1 )
|
|
{
|
|
m_decor[test.x/2][test.y/2].floorIcon = icon;
|
|
}
|
|
}
|
|
|
|
test.x = cel.x +2; // en haut à droite
|
|
test.y = cel.y -2;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
CopyBits(init, bits);
|
|
bits[2] = here[1]?1:0;
|
|
icon = GetSeeIcon(bits, index);
|
|
if ( ChangeBits(init, bits) && icon != -1 )
|
|
{
|
|
m_decor[test.x/2][test.y/2].floorIcon = icon;
|
|
}
|
|
}
|
|
|
|
test.x = cel.x +2; // à droite
|
|
test.y = cel.y;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
CopyBits(init, bits);
|
|
bits[0] = here[1]?1:0;
|
|
bits[2] = here[3]?1:0;
|
|
icon = GetSeeIcon(bits, index);
|
|
if ( ChangeBits(init, bits) && icon != -1 )
|
|
{
|
|
m_decor[test.x/2][test.y/2].floorIcon = icon;
|
|
}
|
|
}
|
|
|
|
test.x = cel.x +2; // en bas à droite
|
|
test.y = cel.y +2;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
CopyBits(init, bits);
|
|
bits[0] = here[3]?1:0;
|
|
icon = GetSeeIcon(bits, index);
|
|
if ( ChangeBits(init, bits) && icon != -1 )
|
|
{
|
|
m_decor[test.x/2][test.y/2].floorIcon = icon;
|
|
}
|
|
}
|
|
|
|
test.x = cel.x; // en bas
|
|
test.y = cel.y +2;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
CopyBits(init, bits);
|
|
bits[0] = here[2]?1:0;
|
|
bits[1] = here[3]?1:0;
|
|
icon = GetSeeIcon(bits, index);
|
|
if ( ChangeBits(init, bits) && icon != -1 )
|
|
{
|
|
m_decor[test.x/2][test.y/2].floorIcon = icon;
|
|
}
|
|
}
|
|
|
|
test.x = cel.x -2; // en bas à gauche
|
|
test.y = cel.y +2;
|
|
if ( GetSeeBits(test, bits, index) )
|
|
{
|
|
CopyBits(init, bits);
|
|
bits[1] = here[2]?1:0;
|
|
icon = GetSeeIcon(bits, index);
|
|
if ( ChangeBits(init, bits) && icon != -1 )
|
|
{
|
|
m_decor[test.x/2][test.y/2].floorIcon = icon;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Cette table donne les directions dans l'ordre
|
|
// est-sud-ouest-nord pour les murs.
|
|
static char tableMur[5*15] =
|
|
{
|
|
20, 1,0,1,0,
|
|
21, 0,1,0,1,
|
|
22, 1,1,0,0,
|
|
23, 0,1,1,0,
|
|
24, 0,0,1,1,
|
|
25, 1,0,0,1,
|
|
26, 1,1,1,1,
|
|
|
|
26, 0,1,1,1,
|
|
26, 1,0,1,1,
|
|
26, 1,1,0,1,
|
|
26, 1,1,1,0,
|
|
|
|
20, 1,0,0,0,
|
|
20, 0,0,1,0,
|
|
21, 0,1,0,0,
|
|
21, 0,0,0,1,
|
|
};
|
|
|
|
static short tableMurDir[4*2] =
|
|
{
|
|
+2, 0, // est
|
|
0,+2, // sur
|
|
-2, 0, // ouest
|
|
0,-2, // nord
|
|
};
|
|
|
|
// Arrange un mur en fonction des autres murs dans toutes
|
|
// les directions.
|
|
// index=0 si mur (20..26)
|
|
// index=1 si palissade (65..71)
|
|
// index=2 si barrière (106..112)
|
|
|
|
void CDecor::ArrangeMur(POINT cel, int &icon, int index)
|
|
{
|
|
int i, x, y, channel;
|
|
int first, last, matiere;
|
|
int icons[4];
|
|
char murs[4];
|
|
|
|
if ( index == 0 )
|
|
{
|
|
first = 20;
|
|
last = 26;
|
|
matiere = 44; // pierres
|
|
}
|
|
if ( index == 1 )
|
|
{
|
|
first = 65;
|
|
last = 71;
|
|
matiere = 36; // planches
|
|
}
|
|
if ( index == 2 )
|
|
{
|
|
first = 106;
|
|
last = 112;
|
|
matiere = 36; // planches
|
|
}
|
|
|
|
for ( i=0 ; i<4 ; i++ )
|
|
{
|
|
x = cel.x + tableMurDir[i*2+0];
|
|
y = cel.y + tableMurDir[i*2+1];
|
|
|
|
if ( IsValid(GetCel(x,y)) )
|
|
{
|
|
icons[i] = m_decor[x/2][y/2].objectIcon;
|
|
if ( icons[i] == matiere ) // pierres/planches ?
|
|
{
|
|
MoveGetObject(GetCel(x,y), channel, icons[i]);
|
|
}
|
|
|
|
if ( icons[i] < first || icons[i] > last )
|
|
{
|
|
icons[i] = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
icons[i] = -1;
|
|
}
|
|
}
|
|
|
|
for ( i=0 ; i<4 ; i++ )
|
|
{
|
|
if ( icons[i] == -1 )
|
|
{
|
|
murs[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
murs[i] = tableMur[(icons[i]-first)*5+1+((i+2)%4)];
|
|
}
|
|
}
|
|
|
|
for ( i=0 ; i<15 ; i++ )
|
|
{
|
|
if ( murs[0] == tableMur[i*5+1] &&
|
|
murs[1] == tableMur[i*5+2] &&
|
|
murs[2] == tableMur[i*5+3] &&
|
|
murs[3] == tableMur[i*5+4] )
|
|
{
|
|
icon = tableMur[i*5+0];
|
|
icon += first-20;
|
|
return;
|
|
}
|
|
}
|
|
|
|
icon = -1;
|
|
}
|
|
|
|
// Arrange les objets avant une construction.
|
|
|
|
void CDecor::ArrangeBuild(POINT cel, int &channel, int &icon)
|
|
{
|
|
int index, i, x, y;
|
|
int first, last, matiere;
|
|
int oldChannel, oldIcon;
|
|
|
|
for ( index=0 ; index<3 ; index++ )
|
|
{
|
|
if ( index == 0 )
|
|
{
|
|
first = 20;
|
|
last = 26;
|
|
matiere = 44; // pierres
|
|
}
|
|
if ( index == 1 )
|
|
{
|
|
first = 65;
|
|
last = 71;
|
|
matiere = 36; // planches
|
|
}
|
|
if ( index == 2 )
|
|
{
|
|
first = 106;
|
|
last = 112;
|
|
matiere = 36; // planches
|
|
}
|
|
|
|
// Rien à faire si pas mur.
|
|
if ( channel != CHOBJECT || icon != last ) continue;
|
|
|
|
oldChannel = m_decor[cel.x/2][cel.y/2].objectChannel;
|
|
oldIcon = m_decor[cel.x/2][cel.y/2].objectIcon;
|
|
|
|
m_decor[cel.x/2][cel.y/2].objectChannel = channel;
|
|
m_decor[cel.x/2][cel.y/2].objectIcon = icon;
|
|
|
|
for ( i=0 ; i<4 ; i++ )
|
|
{
|
|
x = cel.x + tableMurDir[i*2+0];
|
|
y = cel.y + tableMurDir[i*2+1];
|
|
|
|
if ( IsValid(GetCel(x,y)) )
|
|
{
|
|
icon = m_decor[x/2][y/2].objectIcon;
|
|
if ( icon == matiere ) // pierres/planches ?
|
|
{
|
|
MoveGetObject(GetCel(x,y), channel, icon);
|
|
}
|
|
|
|
if ( icon >= first && icon <= last )
|
|
{
|
|
ArrangeMur(GetCel(x,y), icon, index);
|
|
|
|
if ( icon != -1 )
|
|
{
|
|
if ( !MovePutObject(GetCel(x,y), channel, icon) )
|
|
{
|
|
m_decor[x/2][y/2].objectChannel = channel;
|
|
m_decor[x/2][y/2].objectIcon = icon;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
m_decor[cel.x/2][cel.y/2].objectChannel = oldChannel;
|
|
m_decor[cel.x/2][cel.y/2].objectIcon = oldIcon;
|
|
|
|
ArrangeMur(cel, icon, index);
|
|
if ( icon == -1 ) icon = last;
|
|
}
|
|
}
|
|
|
|
// Arrange les objets après une modification.
|
|
|
|
void CDecor::ArrangeObject(POINT cel)
|
|
{
|
|
int channel, icon;
|
|
int first, last;
|
|
int index, i, j, k, x, y;
|
|
POINT vector, test, pos;
|
|
bool bTour;
|
|
|
|
for ( index=0 ; index<3 ; index++ )
|
|
{
|
|
if ( index == 0 )
|
|
{
|
|
first = 20; // murs
|
|
last = 26;
|
|
}
|
|
if ( index == 1 )
|
|
{
|
|
first = 65; // palissades
|
|
last = 71;
|
|
}
|
|
if ( index == 2 )
|
|
{
|
|
first = 106; // barrière
|
|
last = 112;
|
|
}
|
|
|
|
for ( i=0 ; i<4 ; i++ )
|
|
{
|
|
x = cel.x + tableMurDir[i*2+0];
|
|
y = cel.y + tableMurDir[i*2+1];
|
|
|
|
if ( IsValid(GetCel(x,y)) )
|
|
{
|
|
icon = m_decor[x/2][y/2].objectIcon;
|
|
if ( icon >= first && icon <= last )
|
|
{
|
|
ArrangeMur(GetCel(x,y), icon, index);
|
|
|
|
if ( icon != -1 )
|
|
{
|
|
m_decor[x/2][y/2].objectChannel = CHOBJECT;
|
|
m_decor[x/2][y/2].objectIcon = icon;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( m_decor[cel.x/2][cel.y/2].objectIcon == last )
|
|
{
|
|
ArrangeMur(cel, icon, index);
|
|
if ( icon == -1 ) icon = last;
|
|
|
|
m_decor[cel.x/2][cel.y/2].objectChannel = CHOBJECT;
|
|
m_decor[cel.x/2][cel.y/2].objectIcon = icon;
|
|
}
|
|
}
|
|
|
|
// Arrange les rayons entre les tours.
|
|
if ( m_decor[cel.x/2][cel.y/2].objectIcon == 27 || // tour ?
|
|
m_decor[cel.x/2][cel.y/2].objectIcon == -1 ) // rien ?
|
|
{
|
|
for ( i=0 ; i<4 ; i++ )
|
|
{
|
|
vector = GetVector(i*2*16);
|
|
test = cel;
|
|
|
|
bTour = false;
|
|
j = 0;
|
|
while ( true )
|
|
{
|
|
test.x += vector.x*2;
|
|
test.y += vector.y*2;
|
|
|
|
if ( m_decor[test.x/2][test.y/2].objectIcon == 27 ) // tour ?
|
|
{
|
|
bTour = true;
|
|
break;
|
|
}
|
|
|
|
if ( m_decor[test.x/2][test.y/2].objectIcon != -1 &&
|
|
m_decor[test.x/2][test.y/2].objectIcon != 10001-i%2 )
|
|
{
|
|
break;
|
|
}
|
|
|
|
j ++;
|
|
if ( j >= 2+1 ) break;
|
|
}
|
|
|
|
if ( m_decor[cel.x/2][cel.y/2].objectIcon != 27 ) // pas tour ?
|
|
{
|
|
bTour = false;
|
|
}
|
|
|
|
test = cel;
|
|
for ( k=0 ; k<j ; k++ )
|
|
{
|
|
test.x += vector.x*2;
|
|
test.y += vector.y*2;
|
|
|
|
if ( bTour )
|
|
{
|
|
channel = CHOBJECT;
|
|
icon = 10001-i%2; // rayon e-o (10001) ou n-s (10000)
|
|
}
|
|
else
|
|
{
|
|
channel = -1;
|
|
icon = -1;
|
|
}
|
|
m_decor[test.x/2][test.y/2].objectChannel = channel;
|
|
m_decor[test.x/2][test.y/2].objectIcon = icon;
|
|
|
|
if ( !m_bBuild && bTour )
|
|
{
|
|
if ( MoveCreate(test, -1, false, CHOBJECT,-1,
|
|
-1,-1, 9999,1,0, true) )
|
|
{
|
|
MoveAddIcons(test, 5-i%2, true); // éclairs
|
|
}
|
|
|
|
pos = ConvCelToPos(test);
|
|
m_pSound->PlayImage(SOUND_RAYON1, pos);
|
|
}
|
|
|
|
if ( !m_bBuild && !bTour )
|
|
{
|
|
MoveFinish(test);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Test s'il faut remplir le sol ici.
|
|
|
|
bool CDecor::ArrangeFillTestFloor(POINT cel1, POINT cel2)
|
|
{
|
|
POINT cel;
|
|
int icon1, icon2;
|
|
|
|
icon1 = m_fillSearchIcon;
|
|
icon2 = m_fillSearchIcon;
|
|
|
|
if ( m_fillPutChannel == CHFLOOR &&
|
|
m_fillPutIcon == 1 && // met de l'herbe..
|
|
m_fillSearchIcon == 14 ) // ..sur de l'eau ?
|
|
{
|
|
icon1 = 2;
|
|
icon2 = 14; // eau & rives
|
|
}
|
|
|
|
if ( m_fillPutChannel == CHFLOOR &&
|
|
m_fillPutIcon == 14 && // met de l'eau..
|
|
m_fillSearchIcon == 1 ) // ..sur de l'herbe ?
|
|
{
|
|
icon1 = 1;
|
|
icon2 = 13; // herbe & rives
|
|
}
|
|
|
|
for ( cel.x=cel1.x ; cel.x<=cel2.x ; cel.x+=2 )
|
|
{
|
|
for ( cel.y=cel1.y ; cel.y<=cel2.y ; cel.y+=2 )
|
|
{
|
|
if ( !IsValid(cel) ) continue;
|
|
|
|
if ( m_decor[cel.x/2][cel.y/2].floorChannel != m_fillSearchChannel ||
|
|
m_decor[cel.x/2][cel.y/2].floorIcon < icon1 ||
|
|
m_decor[cel.x/2][cel.y/2].floorIcon > icon2 )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if ( m_fillPutChannel == CHFLOOR &&
|
|
m_fillPutIcon == 14 && // met de l'eau ?
|
|
m_decor[cel.x/2][cel.y/2].objectIcon != -1 )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( m_fillPutChannel == CHFLOOR &&
|
|
m_fillPutIcon == 14 && // met de l'eau ?
|
|
IsBlupiHereEx(cel1, cel2, -1, false) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Test s'il faut remplir ici.
|
|
|
|
bool CDecor::ArrangeFillTest(POINT pos)
|
|
{
|
|
POINT cel1, cel2;
|
|
|
|
if ( m_pFillMap[(pos.x/2)+(pos.y/2)*(MAXCELX/2)] == 1 )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if ( m_bFillFloor )
|
|
{
|
|
cel1.x = pos.x-2;
|
|
cel1.y = pos.y-2;
|
|
cel2.x = pos.x+3;
|
|
cel2.y = pos.y+3;
|
|
return ArrangeFillTestFloor(cel1, cel2);
|
|
}
|
|
else
|
|
{
|
|
if ( m_decor[pos.x/2][pos.y/2].objectChannel == m_fillSearchChannel &&
|
|
m_decor[pos.x/2][pos.y/2].objectIcon == m_fillSearchIcon &&
|
|
!IsBlupiHereEx(GetCel(pos.x+0,pos.y+0),
|
|
GetCel(pos.x+1,pos.y+1), -1, false) )
|
|
{
|
|
if ( m_decor[pos.x/2][pos.y/2].floorChannel == CHFLOOR &&
|
|
m_decor[pos.x/2][pos.y/2].floorIcon >= 2 &&
|
|
m_decor[pos.x/2][pos.y/2].floorIcon <= 14 ) // rive ou eau ?
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Modifie le décor lors d'un remplissage.
|
|
|
|
void CDecor::ArrangeFillPut(POINT pos, int channel, int icon)
|
|
{
|
|
if ( m_bFillFloor )
|
|
{
|
|
PutFloor(pos, channel, icon);
|
|
ArrangeFloor(pos);
|
|
}
|
|
else
|
|
{
|
|
if ( icon >= 0 && icon <= 5 ) // plantes ?
|
|
{
|
|
icon = Random(0,5);
|
|
}
|
|
if ( icon >= 6 && icon <= 11 ) // arbres ?
|
|
{
|
|
icon = Random(6,11);
|
|
}
|
|
if ( icon >= 37 && icon <= 43 ) // rochers ?
|
|
{
|
|
icon = Random(37,43);
|
|
}
|
|
PutObject(pos, channel, icon);
|
|
ArrangeObject(pos);
|
|
}
|
|
}
|
|
|
|
// Rempli un sol à partir d'une position donnée.
|
|
|
|
void CDecor::ArrangeFillSearch(POINT pos)
|
|
{
|
|
int startX, endX;
|
|
|
|
// Cherche la borne gauche.
|
|
startX = pos.x;
|
|
endX = pos.x;
|
|
while ( pos.x > 0 && ArrangeFillTest(pos) )
|
|
{
|
|
pos.x -= 2;
|
|
}
|
|
startX = pos.x+2;
|
|
|
|
// Cherche la borne droite.
|
|
pos.x = endX;
|
|
while ( pos.x < MAXCELX-2 && ArrangeFillTest(pos) )
|
|
{
|
|
pos.x += 2;
|
|
}
|
|
endX = pos.x-2;
|
|
|
|
// Rempli toute la ligne trouvée.
|
|
pos.x = startX;
|
|
while ( pos.x <= endX )
|
|
{
|
|
m_pFillMap[(pos.x/2)+(pos.y/2)*(MAXCELX/2)] = 1;
|
|
pos.x += 2;
|
|
}
|
|
|
|
// Cherche la ligne au-dessus.
|
|
if ( pos.y > 0 )
|
|
{
|
|
pos.y -= 2;
|
|
pos.x = startX;
|
|
while ( pos.x <= endX )
|
|
{
|
|
while ( pos.x <= endX && !ArrangeFillTest(pos) )
|
|
{
|
|
pos.x += 2;
|
|
}
|
|
if ( pos.x > endX ) break;
|
|
|
|
if ( ArrangeFillTest(pos) )
|
|
{
|
|
ArrangeFillSearch(pos); // appel récursif
|
|
}
|
|
|
|
while ( pos.x <= endX && ArrangeFillTest(pos) )
|
|
{
|
|
pos.x += 2;
|
|
}
|
|
}
|
|
pos.y += 2;
|
|
}
|
|
|
|
// Cherche la ligne au-dessous.
|
|
if ( pos.y < MAXCELY-2 )
|
|
{
|
|
pos.y += 2;
|
|
pos.x = startX;
|
|
while ( pos.x <= endX )
|
|
{
|
|
while ( pos.x <= endX && !ArrangeFillTest(pos) )
|
|
{
|
|
pos.x += 2;
|
|
}
|
|
if ( pos.x > endX ) break;
|
|
|
|
if ( ArrangeFillTest(pos) )
|
|
{
|
|
ArrangeFillSearch(pos); // appel récursif
|
|
}
|
|
|
|
while ( pos.x <= endX && ArrangeFillTest(pos) )
|
|
{
|
|
pos.x += 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Rempli un sol à partir d'une position donnée.
|
|
|
|
void CDecor::ArrangeFill(POINT pos, int channel, int icon, bool bFloor)
|
|
{
|
|
m_bFillFloor = bFloor;
|
|
|
|
pos.x = (pos.x/2)*2;
|
|
pos.y = (pos.y/2)*2;
|
|
|
|
m_fillPutChannel = channel;
|
|
m_fillPutIcon = icon;
|
|
|
|
if ( bFloor )
|
|
{
|
|
GetFloor(pos, m_fillSearchChannel, m_fillSearchIcon);
|
|
}
|
|
else
|
|
{
|
|
GetObject(pos, m_fillSearchChannel, m_fillSearchIcon);
|
|
}
|
|
|
|
m_pFillMap = (char*)malloc(MAXCELX*MAXCELY*sizeof(char)/4);
|
|
if ( m_pFillMap == NULL ) return;
|
|
memset(m_pFillMap, 0, MAXCELX*MAXCELY*sizeof(char)/4);
|
|
|
|
ArrangeFillSearch(pos);
|
|
|
|
for ( pos.x=0 ; pos.x<MAXCELX ; pos.x+=2 )
|
|
{
|
|
for ( pos.y=0 ; pos.y<MAXCELY ; pos.y+=2 )
|
|
{
|
|
if ( m_pFillMap[(pos.x/2)+(pos.y/2)*(MAXCELX/2)] == 1 )
|
|
{
|
|
ArrangeFillPut(pos, channel, icon);
|
|
}
|
|
}
|
|
}
|
|
|
|
free(m_pFillMap);
|
|
}
|
|
|
|
|
|
// Supprime tous les personnages bloqués dans des murs
|
|
// ou debout sur l'eau.
|
|
|
|
void CDecor::ArrangeBlupi()
|
|
{
|
|
int rank;
|
|
|
|
for ( rank=0 ; rank<MAXBLUPI ; rank++ )
|
|
{
|
|
if ( m_blupi[rank].bExist )
|
|
{
|
|
if ( !IsFreeCel(m_blupi[rank].cel, rank) )
|
|
{
|
|
m_blupi[rank].bExist = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|