git-svn-id: https://scorched3d.svn.sourceforge.net/svnroot/scorched3d/trunk/scorched...
[scorched3d/parasti.git] / src / common / tank / TankDefinition.cpp
blobca8f005a6afe8f96c9c43ae3b774eefab381ba12
1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
3 //
4 // This file is part of Scorched3D.
5 //
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // Scorched3D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with Scorched3D; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ////////////////////////////////////////////////////////////////////////////////
21 #include <tank/TankDefinition.h>
22 #include <tank/Tank.h>
23 #include <tank/TankColorGenerator.h>
24 #include <tank/TankModelStore.h>
25 #include <tank/TankAvatar.h>
26 #include <tank/TankState.h>
27 #include <target/TargetLife.h>
28 #include <target/TargetParachute.h>
29 #include <target/TargetShield.h>
30 #include <target/TargetState.h>
31 #include <tankai/TankAIStore.h>
32 #ifndef S3D_SERVER
33 #include <tankgraph/TargetRendererImplTank.h>
34 #endif
35 #include <common/RandomGenerator.h>
36 #include <common/OptionsScorched.h>
37 #include <common/Defines.h>
38 #include <weapons/AccessoryStore.h>
39 #include <engine/ScorchedContext.h>
40 #include <server/ScorchedServer.h>
42 TankDefinition::TankDefinition() :
43 team_(0),
44 life_(100), boundingsphere_(true),
45 size_(2, 2, 2),
46 driveovertodestroy_(false)
48 shadow_.setDrawShadow(false);
51 TankDefinition::~TankDefinition()
55 bool TankDefinition::readXML(XMLNode *node, const char *base)
57 node->getNamedChild("name", name_, false);
58 node->getNamedChild("life", life_, false);
59 node->getNamedChild("shield", shield_, false);
60 node->getNamedChild("parachute", parachute_, false);
61 node->getNamedChild("boundingsphere", boundingsphere_, false);
63 if (!node->getNamedChild("ai", ai_)) return false;
64 if (!node->getNamedChild("model", tankmodel_)) return false;
65 node->getNamedChild("team", team_, false);
67 node->getNamedChild("driveovertodestroy", driveovertodestroy_, false);
68 node->getNamedChild("removeaction", removeaction_, false);
69 node->getNamedChild("burnaction", burnaction_, false);
71 if (!shadow_.readXML(node, base)) return false;
72 if (!groups_.readXML(node)) return false;
74 return node->failChildren();
77 Tank *TankDefinition::createTank(unsigned int playerId,
78 FixedVector &position,
79 ScorchedContext &context,
80 RandomGenerator &generator)
82 Vector color = TankColorGenerator::getTeamColor(team_);
83 if (team_ == 0) color = Vector(0.7f, 0.7f, 0.7f);
85 TankModel *model =
86 context.getTankModels().getModelByName(
87 tankmodel_.c_str(),
88 team_,
89 true);
90 if (!model || strcmp("Random", model->getName()) == 0)
92 S3D::dialogExit("TankDefinition",
93 S3D::formatStringBuffer("Cannot find a tank model named \"%s\"",
94 tankmodel_.c_str()));
97 Tank *tank = new Tank(context, playerId, 0,
98 name_, color, model->getName(), model->getTypeName());
99 tank->getLife().setBoundingSphere(boundingsphere_);
101 if (context.getServerMode())
103 TankAI *ai = ScorchedServer::instance()->getTankAIs().getAIByName(ai_.c_str());
104 if (!ai)
106 S3D::dialogExit("TankDefinition",
107 S3D::formatStringBuffer("Cannot find a tank ai named \"%s\"",
108 ai_.c_str()));
111 tank->setTankAI(ai->createCopy(tank));
112 std::string uniqueId = S3D::formatStringBuffer("Tank - %u", playerId);
113 tank->setUniqueId(uniqueId.c_str());
115 else
117 #ifndef S3D_SERVER
118 tank->setRenderer(new TargetRendererImplTank(tank));
119 #endif
122 if (context.getOptionsGame().getTeams() > 1)
124 tank->setTeam(team_);
126 tank->getAvatar().loadFromFile(S3D::getDataFile("data/avatars/computer.png"));
127 tank->getLife().setMaxLife(life_);
128 tank->getLife().setSize(size_);
129 tank->getTargetState().setDriveOverToDestroy(driveovertodestroy_);
130 tank->getState().setState(TankState::sInitializing);
131 tank->getState().setState(TankState::sPending);
132 tank->newMatch();
133 tank->newGame();
135 if (shield_.c_str()[0] && 0 != strcmp(shield_.c_str(), "none"))
137 Accessory *shield = context.getAccessoryStore().
138 findByPrimaryAccessoryName(shield_.c_str());
139 if (!shield)
141 S3D::dialogExit("Scorched3D",
142 S3D::formatStringBuffer("Failed to find shield named \"%s\"",
143 shield_.c_str()));
146 tank->getShield().setCurrentShield(shield);
149 if (parachute_.c_str()[0] && 0 != strcmp(parachute_.c_str(), "none"))
151 Accessory *parachute = context.getAccessoryStore().
152 findByPrimaryAccessoryName(parachute_.c_str());
153 if (!parachute)
155 S3D::dialogExit("Scorched3D",
156 S3D::formatStringBuffer("Failed to find parachute named \"%s\"",
157 parachute_.c_str()));
160 tank->getParachute().setCurrentParachute(parachute);
163 if (removeaction_.c_str()[0] && 0 != strcmp(removeaction_.c_str(), "none"))
165 Accessory *action = context.getAccessoryStore().
166 findByPrimaryAccessoryName(removeaction_.c_str());
167 if (!action || action->getType() != AccessoryPart::AccessoryWeapon)
169 S3D::dialogExit("Scorched3D",
170 S3D::formatStringBuffer("Failed to find death action \"%s\"",
171 removeaction_.c_str()));
174 tank->setDeathAction((Weapon *) action->getAction());
176 if (burnaction_.c_str()[0] && 0 != strcmp(burnaction_.c_str(), "none"))
178 Accessory *action = context.getAccessoryStore().
179 findByPrimaryAccessoryName(burnaction_.c_str());
180 if (!action || action->getType() != AccessoryPart::AccessoryWeapon)
182 S3D::dialogExit("Scorched3D",
183 S3D::formatStringBuffer("Failed to find burn action \"%s\"",
184 burnaction_.c_str()));
187 tank->setBurnAction((Weapon *) action->getAction());
190 tank->getLife().setTargetPosition(position);
192 groups_.addToGroups(context, &tank->getGroup(), false);
194 return tank;