/*
FinalSun/FinalAlert 2 Mission Editor
Copyright (C) 1999-2024 Electronic Arts, Inc.
Authored by Matthias Wagner
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
// CliffModifier.cpp: Implementierung der Klasse CCliffModifier.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "stdafx.h"
#include "CliffModifier.h"
#include "variables.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////
CCliffModifier::CCliffModifier()
{
}
CCliffModifier::~CCliffModifier()
{
}
BOOL CCliffModifier::PlaceCliff(DWORD dwXFrom, DWORD dwYFrom, DWORD dwXDest, DWORD dwYDest, BOOL bAlternative)
{
m_bAlternative=bAlternative;
int x_diff, y_diff;
x_diff=dwXDest-dwXFrom;
y_diff=dwYDest-dwYFrom;
if(x_diff>0 && y_diff>0 && ((float)y_diff)/((float)x_diff) > 1.33f)
{
x_diff=0;
dwXDest=dwXFrom;
}
if(x_diff<0 && y_diff>0 && ((float)y_diff)/(-(float)x_diff) > 1.33f)
{
x_diff=0;
dwXDest=dwXFrom;
}
if(x_diff>0 && y_diff<0 && ((float)-y_diff)/((float)x_diff) > 1.33f)
{
x_diff=0;
dwXDest=dwXFrom;
}
if(x_diff<0 && y_diff<0 && (-(float)y_diff)/(-(float)x_diff) > 1.33f)
{
x_diff=0;
dwXDest=dwXFrom;
}
if(y_diff>0 && x_diff>0 && ((float)x_diff)/((float)y_diff) > 2)
{
y_diff=0;
dwYDest=dwYFrom;
}
if(y_diff<0 && x_diff>0 && ((float)x_diff)/(-(float)y_diff) > 2)
{
y_diff=0;
dwYDest=dwYFrom;
}
if(y_diff>0 && x_diff<0 && ((float)-x_diff)/((float)y_diff) > 2)
{
y_diff=0;
dwYDest=dwYFrom;
}
if(y_diff<0 && x_diff<0 && (-(float)x_diff)/(-(float)y_diff) > 2)
{
y_diff=0;
dwYDest=dwYFrom;
}
m_dwFrom=dwXFrom + dwYFrom*Map->GetIsoSize();
m_dwTo=dwXDest + dwYDest*Map->GetIsoSize();
if(!x_diff && !y_diff) return FALSE;
if(x_diff && y_diff)
{
if((x_diff>0 && y_diff>0))
{
m_direction=cd_verticdiag_bottom;
}
else if((x_diff<0 && y_diff<0))
{
m_direction=cd_verticdiag_top;
}
else if((x_diff<0 && y_diff>0) )
{
m_direction=cd_horizdiag_right;
}
else if(x_diff>0 && y_diff<0)
{
m_direction=cd_horizdiag_left;
}
}
else if(y_diff<0)
{
m_direction=cd_horiz_left;
}
else if(y_diff>0)
{
m_direction=cd_horiz_right;
}
else if(x_diff<0)
{
m_direction=cd_vertic_top;
}
else if(x_diff>0)
{
m_direction=cd_vertic_bottom;
}
switch(m_direction)
{
case cd_horiz_left:
m_addx=0;
m_addy=-1;
break;
case cd_horiz_right:
m_addx=0;
m_addy=1;
break;
case cd_horizdiag_left:
m_addx=1;
m_addy=-1;
break;
case cd_horizdiag_right:
m_addx=-1;
m_addy=1;
break;
case cd_vertic_top:
m_addx=-1;
m_addy=0;
break;
case cd_vertic_bottom:
m_addx=1;
m_addy=0;
break;
case cd_verticdiag_top:
m_addx=-1;
m_addy=-1;
break;
case cd_verticdiag_bottom:
m_addx=1;
m_addy=1;
break;
}
int i,e;
DWORD dwCurPos=m_dwFrom;
int startheight=Map->GetHeightAt(dwCurPos);
DWORD dwLastTile=-1;
FIELDDATA* fd=Map->GetFielddataAt(dwCurPos);
int ground=fd->wGround;
int subtile=fd->bSubTile;
if(ground==0xFFFF) ground=0;
startheight-=(*tiledata)[ground].tiles[subtile].bZHeight;
ModifyStartPos(&dwCurPos, FALSE);
BOOL bSmall=FALSE;
DWORD dwFirstStartPos=dwCurPos;
DWORD dwTile=GetTileToPlace(dwCurPos, &bSmall);
BOOL bFirstPos=TRUE;
while(dwCurPos!=m_dwTo)
{
ModifyCurrentPos(&dwCurPos, TRUE, bSmall);
if(!bFirstPos)
{
dwTile=GetTileToPlace(dwCurPos, &bSmall);
dwLastTile=dwTile;
}
else
bFirstPos=FALSE;
if(dwTile==-1) break;
TILEDATA* t=&(*tiledata)[dwTile];
if(m_addx<0) dwCurPos+=t->cx*m_addx;
if(m_addy<0) dwCurPos+=t->cy*m_addy*Map->GetIsoSize();
int o=0;
DWORD dwTmpTile=dwTile;
while(dwFirstStartPos!=dwCurPos && dwTile==dwLastTile)
{
o++;
if(o==10) break;
dwTmpTile=GetTileToPlace(dwCurPos, &bSmall);
if((*tiledata)[dwTmpTile].cx==(*tiledata)[dwTile].cx && (*tiledata)[dwTile].cy==(*tiledata)[dwTmpTile].cy)
dwTile=dwTmpTile;
}
t=&(*tiledata)[dwTile];
int p=0;
for(i=0;icx;i++)
{
for(e=0;ecy;e++)
{
if(t->tiles[p].pic!=NULL)
{
Map->SetHeightAt(dwCurPos+i+e*Map->GetIsoSize(), startheight+t->tiles[p].bZHeight);
Map->SetTileAt(dwCurPos+i+e*Map->GetIsoSize(), dwTile, p);
}
p++;
}
}
if(m_addx>0) dwCurPos+=t->cx*m_addx;
if(m_addy>0) dwCurPos+=t->cy*m_addy*Map->GetIsoSize();
ModifyCurrentPos(&dwCurPos, FALSE, bSmall);
dwLastTile=dwTile;
}
return TRUE;
}
void CCliffModifier::ModifyStartPos(DWORD *dwStartPos, BOOL bSmall)
{
}
void CCliffModifier::ModifyCurrentPos(DWORD *dwPos, BOOL bBeforePlacing, BOOL bSmall)
{
}
DWORD CCliffModifier::GetTileToPlace(DWORD dwPos, BOOL* bSmall)
{
vector careables;
vector useables;
map notusedascliff;
CString type;
int count=0;
switch(m_direction)
{
case cd_horiz_left:
case cd_horiz_right:
type="horiz_";
break;
case cd_horizdiag_left:
case cd_horizdiag_right:
type="horiz_diag_";
break;
case cd_vertic_top:
case cd_vertic_bottom:
type="vertic_";
break;
case cd_verticdiag_top:
case cd_verticdiag_bottom:
type="vertic_diag_";
break;
}
CString sec=GetDataSection();
CIniFile& ini=Map->GetIniFile();
if(g_data.sections.find(sec+ini.sections["Map"].values["Theater"])!=g_data.sections.end())
sec=sec+ini.sections["Map"].values["Theater"];
count=atoi(g_data.sections[sec].values[type+"c"]);
int i;
DWORD dwStartSet=0;
/*for(i=0;i<(*tiledata_count);i++)
{
if( (!m_bAlternative && (*tiledata)[i].wTileSet==cliffset) || (m_bAlternative && (*tiledata)[i].wTileSet==cliff2set))
{
dwStartSet=i;
break;
}
}*/
// a bit faster:
if(m_bAlternative) dwStartSet=cliff2set_start;
else dwStartSet=cliffset_start;
for(i=0;iGetIsoSize();
ModifyStartPos(&dwCurPos, FALSE);
int e;
for(i=-1;i<2;i++)
{
for(e=-1;e<2;e++)
{
FIELDDATA* fd=Map->GetFielddataAt(dwCurPos+i+e*isosize);
int ground=fd->wGround;
if(ground==0xFFFF) ground=0;
if( (*tiledata)[ground].wTileSet==cliffset && notusedascliff.find(ground)==notusedascliff.end())
{
if(i==0 && e==-1) {corner_searched="cornerleft_";break;}
if(i==0 && e==1) {corner_searched="cornerright_";break;}
if(i==-1 && e==0) {corner_searched="cornertop_";break;}
if(i==1 && e==0) {corner_searched="cornerbottom_";break;}
/*if(e==-1) {corner_searched="cornerleft_";break;}
if(e==1) {corner_searched="cornerright_";break;}
if(i==-1) {corner_searched="cornertop_";break;}
if(i==1) {corner_searched="cornerbottom_";break;}*/
}
}
if(corner_searched.GetLength()>0) break;
}
BOOL bCornerFound=FALSE;
if(g_data.sections[sec].FindName(type+corner_searched+"c")>=0)
{
int icount=atoi(g_data.sections[sec].values[type+corner_searched+"c"]);
if(icount)
{
bCornerFound=TRUE;
count=icount;
}
}
if(!bCornerFound) corner_searched="";
if(count==0) return -1;
DWORD dwX=dwPos%Map->GetIsoSize();
DWORD dwY=dwPos/Map->GetIsoSize();
DWORD dwDX=m_dwTo%Map->GetIsoSize();
DWORD dwDY=m_dwTo/Map->GetIsoSize();
for(i=0;i0 && dwX+m_addx*t.cx>dwDX) continue;
if(m_addy>0 && dwY+m_addy*t.cy>dwDY) continue;
if(m_addx<0 && dwX+m_addx*t.cxt1.cx || t.cy>t1.cy) {*bSmall=TRUE; break;}
}
// check for water
BOOL bWater=FALSE;
for(i=0;iGetFielddataAt(dwPos+i+e*Map->GetIsoSize());
int ground=fd->wGround;
if(ground==0xFFFF) ground=0;
if((i==t1.cx-1 || e==t1.cy-1) && (*tiledata)[ground].tiles[fd->bSubTile].bHackedTerrainType==TERRAINTYPE_WATER)
{
bWater=TRUE;
break;
}
}
if(bWater) break;
}
if(bWater && useables[k]-dwStartSet<22)
{
CString tset;
char c[50];
int watercliffs=atoi(tiles->sections["General"].values["WaterCliffs"]);
if(m_bAlternative) watercliffs=cliffwater2set;
itoa(watercliffs, c, 10);
int e;
for(e=0;e<4-strlen(c);e++)
tset+="0";
tset+=c;
CString sec="TileSet";
sec+=tset;
if(tiles->sections.find(sec)==tiles->sections.end()) return useables[k];
if(atoi(tiles->sections[sec].values["TilesInSet"])>useables[k]-dwStartSet)
{
DWORD dwStartWaterSet=0;
for(i=0;i<(*tiledata_count);i++)
{
if((*tiledata)[i].wTileSet==watercliffs)
{
dwStartWaterSet=i;
return dwStartWaterSet+(useables[k]-dwStartSet);
}
}
}
}
return useables[k];
}