2006-03-31 05:30:34 +02:00
# include "precompiled.h"
# include "BaseFormation.h"
# include "CLogger.h"
# include "CStr.h"
2006-04-09 01:47:29 +02:00
# include "maths/MathUtil.h"
2006-03-31 05:30:34 +02:00
# define LOG_CATEGORY "Formation"
CBaseFormation : : CBaseFormation ( )
{
m_numSlots = 0 ;
}
bool CBaseFormation : : loadXML ( CStr filename )
{
CXeromyces XeroFile ;
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
if ( XeroFile . Load ( filename ) ! = PSRETURN_OK )
return false ;
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
# define EL(x) int el_##x = XeroFile.getElementID(#x)
# define AT(x) int at_##x = XeroFile.getAttributeID(#x)
EL ( formation ) ;
EL ( fl ) ;
EL ( rk ) ;
EL ( blank ) ;
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
AT ( tag ) ;
AT ( bonus ) ;
AT ( bonustype ) ;
AT ( bonusval ) ;
AT ( penalty ) ;
AT ( penaltytype ) ;
AT ( penaltyval ) ;
2006-04-09 00:34:54 +02:00
AT ( anglepenalty ) ;
AT ( anglepenaltydivs ) ;
AT ( anglepenaltytype ) ;
AT ( anglepenaltyval ) ;
2006-03-31 05:30:34 +02:00
AT ( required ) ;
AT ( next ) ;
AT ( prior ) ;
AT ( movement ) ;
AT ( filespacing ) ;
AT ( rankspacing ) ;
AT ( category ) ;
AT ( order ) ;
# undef AT
# undef EL
XMBElement Root = XeroFile . getRoot ( ) ;
if ( Root . getNodeName ( ) ! = el_formation )
{
LOG ( ERROR , LOG_CATEGORY , " CBaseFormation::LoadXML: XML root was not \" Formation \" in file %s. Load failed. " , filename . c_str ( ) ) ;
return ( false ) ;
}
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
//Load in single attributes
XMBAttributeList Attributes = Root . getAttributes ( ) ;
for ( int i = 0 ; i < Attributes . Count ; + + i )
{
XMBAttribute Attr = Attributes . item ( i ) ;
2006-04-09 00:34:54 +02:00
if ( Attr . Name = = at_tag )
2006-03-31 05:30:34 +02:00
m_tag = CStr ( Attr . Value ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_bonus )
2006-03-31 05:30:34 +02:00
m_bonus = CStr ( Attr . Value ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_bonustype )
2006-03-31 05:30:34 +02:00
m_bonusType = CStr ( Attr . Value ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_bonusval )
2006-03-31 05:30:34 +02:00
m_bonusVal = CStr ( Attr . Value ) . ToFloat ( ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_penalty )
2006-03-31 05:30:34 +02:00
m_penalty = CStr ( Attr . Value ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_penaltytype )
2006-03-31 05:30:34 +02:00
m_penaltyType = CStr ( Attr . Value ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_penaltyval )
2006-03-31 05:30:34 +02:00
m_penaltyVal = CStr ( Attr . Value ) . ToFloat ( ) ;
2006-04-09 01:47:29 +02:00
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_anglepenalty )
m_anglePenalty = CStr ( Attr . Value ) ;
else if ( Attr . Name = = at_anglepenaltydivs )
m_anglePenaltyDivs = CStr ( Attr . Value ) . ToInt ( ) ;
else if ( Attr . Name = = at_anglepenaltytype )
m_anglePenaltyType = CStr ( Attr . Value ) ;
else if ( Attr . Name = = at_anglepenaltyval )
m_anglePenaltyVal = CStr ( Attr . Value ) . ToFloat ( ) ;
2006-04-09 01:47:29 +02:00
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_required )
2006-03-31 05:30:34 +02:00
m_required = CStr ( Attr . Value ) . ToInt ( ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_next )
2006-03-31 05:30:34 +02:00
m_next = CStr ( Attr . Value ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_prior )
2006-03-31 05:30:34 +02:00
m_prior = CStr ( Attr . Value ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_movement )
2006-03-31 05:30:34 +02:00
m_movement = CStr ( Attr . Value ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_rankspacing )
2006-03-31 05:30:34 +02:00
m_rankSpacing = CStr ( Attr . Value ) . ToFloat ( ) ;
2006-04-09 00:34:54 +02:00
else if ( Attr . Name = = at_filespacing )
2006-03-31 05:30:34 +02:00
m_fileSpacing = CStr ( Attr . Value ) . ToFloat ( ) ;
else
{
2006-04-09 00:34:54 +02:00
const char * invAttr = XeroFile . getAttributeString ( Attr . Name ) . c_str ( ) ;
LOG ( ERROR , LOG_CATEGORY , " CBaseFormation::LoadXML: Invalid attribute %s defined in formation file %s. Load failed. " , invAttr , filename . c_str ( ) ) ;
2006-03-31 05:30:34 +02:00
return ( false ) ;
}
}
XMBElementList RootChildren = Root . getChildNodes ( ) ;
int file = 0 ;
int rank = 0 ;
int maxrank = 0 ;
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
//Read in files and ranks
for ( int i = 0 ; i < RootChildren . Count ; + + i )
{
XMBElement RootChild = RootChildren . item ( i ) ;
int ChildName = RootChild . getNodeName ( ) ;
if ( ChildName = = el_fl )
{
rank = 0 ;
XMBAttributeList FileAttribList = RootChild . getAttributes ( ) ;
//Load default category
CStr FileCatValue = FileAttribList . getNamedItem ( at_category ) ;
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
//Specific slots in this file (row)
XMBElementList RankNodes = RootChild . getChildNodes ( ) ;
for ( int r = 0 ; r < RankNodes . Count ; + + r )
{
XMBElement Rank = RankNodes . item ( r ) ;
if ( Rank . getNodeName ( ) = = el_blank )
{
+ + rank ;
continue ;
}
else if ( Rank . getNodeName ( ) ! = el_rk )
return false ;
//error
XMBAttributeList RankAttribList = Rank . getAttributes ( ) ;
int order = CStr ( RankAttribList . getNamedItem ( at_order ) ) . ToInt ( ) ;
CStr category = CStr ( RankAttribList . getNamedItem ( at_category ) ) ;
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
if ( order < = 0 )
{
2006-04-14 05:14:43 +02:00
LOG ( ERROR , LOG_CATEGORY , " CBaseFormation::LoadXML: Invalid (negative number or 0) order defined in formation file %s. The game will try to continue anyway. " , filename . c_str ( ) ) ;
2006-03-31 05:30:34 +02:00
continue ;
}
- - order ; //We need this to be in line with arrays, so start at 0
//if ( category.length() )
//AssignCategory(order, category);
//else
AssignCategory ( order , FileCatValue ) ;
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
m_slots [ order ] . fileOff = file * m_fileSpacing ;
m_slots [ order ] . rankOff = rank * m_rankSpacing ;
+ + m_numSlots ;
+ + rank ;
}
if ( rank > maxrank )
maxrank = rank ;
+ + file ;
} //if el_fl
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
else if ( ChildName = = el_blank )
+ + file ;
}
float centerx = maxrank * m_rankSpacing / 2.0f ;
float centery = file * m_fileSpacing / 2.0f ;
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
//Here we check to make sure no order was skipped over. If so, failure, because we rely
2006-04-09 01:47:29 +02:00
//on a linearly accessible slots in entityformation.cpp.
2006-03-31 05:30:34 +02:00
for ( int i = 0 ; i < m_numSlots ; + + i )
{
if ( m_slots . find ( i ) = = m_slots . end ( ) )
{
2006-04-14 05:14:43 +02:00
LOG ( ERROR , LOG_CATEGORY , " CBaseFormation::LoadXML: Missing orders in %s. Load failed. " , filename . c_str ( ) ) ;
2006-03-31 05:30:34 +02:00
return false ;
}
else
{
m_slots [ i ] . rankOff = m_slots [ i ] . rankOff - centerx ;
m_slots [ i ] . fileOff = m_slots [ i ] . fileOff - centery ;
}
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
}
return true ;
}
void CBaseFormation : : AssignCategory ( int order , CStr category )
{
category . Remove ( CStr ( " , " ) ) ;
category = category + " " ; //So the final word will be pushed as well
CStr temp ;
2006-04-09 01:47:29 +02:00
2006-03-31 05:30:34 +02:00
//Push categories until last space
while ( ( temp = category . BeforeFirst ( " " ) ) ! = " " )
{
m_slots [ order ] . category . push_back ( temp ) ;
//Don't use remove because certain categories could be substrings of others
size_t off = category . find ( temp ) ;
category . erase ( off , temp . length ( ) ) ;
}
}