1 // Description:
2 //   Enemy factory to help create enemy objects.
3 //
4 // Copyright (C) 2001 Frank Becker
5 //
6 // This program is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free Software
8 // Foundation;  either version 2 of the License,  or (at your option) any  later
9 // version.
10 //
11 // This program is distributed in the hope that it will be useful,  but  WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
14 //
15 #include <string>
16 
17 #include <LevelPack.hpp>
18 #include <EnemyFactory.hpp>
19 #include <LPathManager.hpp>
20 #include <SimpleEnemy.hpp>
21 #include <Boss1Enemy.hpp>
22 
23 enum EnemyType
24 {
25     eSimpleEnemy = 0,
26     eBoss1 = 1
27 };
28 
29 //helper
strToFloat(const string & str)30 inline static float strToFloat( const string &str)
31 {
32     return (float)atof( str.c_str());
33 }
34 
strToInt(const string & str)35 inline static int strToInt( const string &str)
36 {
37     return atoi( str.c_str());
38 }
39 
40 //count siblings of the same type
countSiblings(TiXmlNode * node,const string & name)41 inline static int countSiblings( TiXmlNode *node, const string & name)
42 {
43     int count = 0;
44     while( node)
45     {
46 	count++;
47 	node = node->NextSibling( name.c_str());
48     }
49     return count;
50 }
51 
createEnemy(TiXmlNode * enemyNode)52 void EnemyFactory::createEnemy( TiXmlNode *enemyNode)
53 {
54     TiXmlNode *node;
55     TiXmlElement *elem;
56 
57     LPathManager &lpm = *LPathManagerS::instance();
58 
59     LEnemy *enemy = new LEnemy();
60 
61     elem = enemyNode->ToElement();
62     enemy->spawnTime = strToFloat( elem->Attribute("spawnTime"));
63     EnemyType enemyType = eSimpleEnemy;
64     if( elem->Attribute("type"))
65 	enemyType = (EnemyType)strToInt(elem->Attribute("type"));
66 
67     node = enemyNode->FirstChild("Model");
68     elem = node->ToElement();
69     enemy->modelName = elem->Attribute("Name");
70 
71     node = enemyNode->FirstChild("SpawnPoint");
72     elem = node->ToElement();
73     enemy->spawnPoint.x = strToFloat( elem->Attribute("x"));
74     enemy->spawnPoint.y = strToFloat( elem->Attribute("y"));
75     enemy->spawnPoint.z = strToFloat( elem->Attribute("z"));
76 
77     node = enemyNode->FirstChild("Home");
78     elem = node->ToElement();
79     enemy->home.x = strToFloat( elem->Attribute("x"));
80     enemy->home.y = strToFloat( elem->Attribute("y"));
81     enemy->home.z = strToFloat( elem->Attribute("z"));
82 
83     node = enemyNode->FirstChild("EntryPath");
84     elem = node->ToElement();
85     enemy->entry = lpm.getPath( elem->Attribute("Name"));
86 
87     node = enemyNode->FirstChild("IdlePath");
88     elem = node->ToElement();
89     enemy->idle = lpm.getPath( elem->Attribute("Name"));
90 
91     node = enemyNode->FirstChild("AttackPath");
92     enemy->numAttackPaths = countSiblings( node, "AttackPath");
93     enemy->attack = new LPath*[ enemy->numAttackPaths];
94     for( int i=0; i< enemy->numAttackPaths; i++)
95     {
96 	elem = node->ToElement();
97 	enemy->attack[ i] = lpm.getPath( elem->Attribute("Name"));
98 	node = node->NextSibling( "AttackPath");
99     }
100 
101     node = enemyNode->FirstChild("RetreatPath");
102     enemy->numRetreatPaths = countSiblings( node, "RetreatPath");
103     enemy->retreat = new LPath*[ enemy->numRetreatPaths];
104     for( int i=0; i< enemy->numRetreatPaths; i++)
105     {
106 	elem = node->ToElement();
107 	enemy->retreat[ i] = lpm.getPath( elem->Attribute("Name"));
108 	node = node->NextSibling( "RetreatPath");
109     }
110 
111     switch( enemyType)
112     {
113 	default:
114 	case eSimpleEnemy:
115 	    new SimpleEnemy( enemy);
116 	    break;
117 	case eBoss1:
118 	    new Boss1Enemy( enemy);
119 	    break;
120     }
121 }
122