00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <tank/TankDefinition.h>
00022 #include <tank/Tank.h>
00023 #include <tank/TankColorGenerator.h>
00024 #include <tank/TankModelStore.h>
00025 #include <tank/TankAvatar.h>
00026 #include <tank/TankState.h>
00027 #include <target/TargetLife.h>
00028 #include <target/TargetParachute.h>
00029 #include <target/TargetShield.h>
00030 #include <target/TargetState.h>
00031 #include <tankai/TankAIStore.h>
00032 #ifndef S3D_SERVER
00033 #include <tankgraph/TargetRendererImplTank.h>
00034 #endif
00035 #include <common/RandomGenerator.h>
00036 #include <common/OptionsScorched.h>
00037 #include <common/Defines.h>
00038 #include <weapons/AccessoryStore.h>
00039 #include <engine/ScorchedContext.h>
00040 #include <server/ScorchedServer.h>
00041
00042 TankDefinition::TankDefinition() :
00043 team_(0),
00044 life_(100), boundingsphere_(true),
00045 size_(2, 2, 2),
00046 driveovertodestroy_(false)
00047 {
00048 shadow_.setDrawShadow(false);
00049 }
00050
00051 TankDefinition::~TankDefinition()
00052 {
00053 }
00054
00055 bool TankDefinition::readXML(XMLNode *node, const char *base)
00056 {
00057 node->getNamedChild("name", name_, false);
00058 node->getNamedChild("life", life_, false);
00059 node->getNamedChild("shield", shield_, false);
00060 node->getNamedChild("parachute", parachute_, false);
00061 node->getNamedChild("boundingsphere", boundingsphere_, false);
00062
00063 if (!node->getNamedChild("ai", ai_)) return false;
00064 if (!node->getNamedChild("model", tankmodel_)) return false;
00065 node->getNamedChild("team", team_, false);
00066
00067 node->getNamedChild("driveovertodestroy", driveovertodestroy_, false);
00068 node->getNamedChild("removeaction", removeaction_, false);
00069 node->getNamedChild("burnaction", burnaction_, false);
00070
00071 if (!shadow_.readXML(node, base)) return false;
00072 if (!groups_.readXML(node)) return false;
00073
00074 return node->failChildren();
00075 }
00076
00077 Tank *TankDefinition::createTank(unsigned int playerId,
00078 FixedVector &position,
00079 ScorchedContext &context,
00080 RandomGenerator &generator)
00081 {
00082 Vector color = TankColorGenerator::getTeamColor(team_);
00083 if (team_ == 0) color = Vector(0.7f, 0.7f, 0.7f);
00084
00085 TankModel *model =
00086 context.getTankModels().getModelByName(
00087 tankmodel_.c_str(),
00088 team_,
00089 true);
00090 if (!model || strcmp("Random", model->getName()) == 0)
00091 {
00092 S3D::dialogExit("TankDefinition",
00093 S3D::formatStringBuffer("Cannot find a tank model named \"%s\"",
00094 tankmodel_.c_str()));
00095 }
00096
00097 Tank *tank = new Tank(context, playerId, 0,
00098 name_, color, model->getName(), model->getTypeName());
00099 tank->getLife().setBoundingSphere(boundingsphere_);
00100
00101 if (context.getServerMode())
00102 {
00103 TankAI *ai = ScorchedServer::instance()->getTankAIs().getAIByName(ai_.c_str());
00104 if (!ai)
00105 {
00106 S3D::dialogExit("TankDefinition",
00107 S3D::formatStringBuffer("Cannot find a tank ai named \"%s\"",
00108 ai_.c_str()));
00109 }
00110
00111 tank->setTankAI(ai->createCopy(tank));
00112 std::string uniqueId = S3D::formatStringBuffer("Tank - %u", playerId);
00113 tank->setUniqueId(uniqueId.c_str());
00114 }
00115 else
00116 {
00117 #ifndef S3D_SERVER
00118 tank->setRenderer(new TargetRendererImplTank(tank));
00119 #endif
00120 }
00121
00122 if (context.getOptionsGame().getTeams() > 1)
00123 {
00124 tank->setTeam(team_);
00125 }
00126 tank->getAvatar().loadFromFile(S3D::getDataFile("data/avatars/computer.png"));
00127 tank->getLife().setMaxLife(life_);
00128 tank->getLife().setSize(size_);
00129 tank->getTargetState().setDriveOverToDestroy(driveovertodestroy_);
00130 tank->getState().setState(TankState::sInitializing);
00131 tank->getState().setState(TankState::sPending);
00132 tank->newMatch();
00133 tank->newGame();
00134
00135 if (shield_.c_str()[0] && 0 != strcmp(shield_.c_str(), "none"))
00136 {
00137 Accessory *shield = context.getAccessoryStore().
00138 findByPrimaryAccessoryName(shield_.c_str());
00139 if (!shield)
00140 {
00141 S3D::dialogExit("Scorched3D",
00142 S3D::formatStringBuffer("Failed to find shield named \"%s\"",
00143 shield_.c_str()));
00144 }
00145
00146 tank->getShield().setCurrentShield(shield);
00147 }
00148
00149 if (parachute_.c_str()[0] && 0 != strcmp(parachute_.c_str(), "none"))
00150 {
00151 Accessory *parachute = context.getAccessoryStore().
00152 findByPrimaryAccessoryName(parachute_.c_str());
00153 if (!parachute)
00154 {
00155 S3D::dialogExit("Scorched3D",
00156 S3D::formatStringBuffer("Failed to find parachute named \"%s\"",
00157 parachute_.c_str()));
00158 }
00159
00160 tank->getParachute().setCurrentParachute(parachute);
00161 }
00162
00163 if (removeaction_.c_str()[0] && 0 != strcmp(removeaction_.c_str(), "none"))
00164 {
00165 Accessory *action = context.getAccessoryStore().
00166 findByPrimaryAccessoryName(removeaction_.c_str());
00167 if (!action || action->getType() != AccessoryPart::AccessoryWeapon)
00168 {
00169 S3D::dialogExit("Scorched3D",
00170 S3D::formatStringBuffer("Failed to find death action \"%s\"",
00171 removeaction_.c_str()));
00172 }
00173
00174 tank->setDeathAction((Weapon *) action->getAction());
00175 }
00176 if (burnaction_.c_str()[0] && 0 != strcmp(burnaction_.c_str(), "none"))
00177 {
00178 Accessory *action = context.getAccessoryStore().
00179 findByPrimaryAccessoryName(burnaction_.c_str());
00180 if (!action || action->getType() != AccessoryPart::AccessoryWeapon)
00181 {
00182 S3D::dialogExit("Scorched3D",
00183 S3D::formatStringBuffer("Failed to find burn action \"%s\"",
00184 burnaction_.c_str()));
00185 }
00186
00187 tank->setBurnAction((Weapon *) action->getAction());
00188 }
00189
00190 tank->getLife().setTargetPosition(position);
00191
00192 groups_.addToGroups(context, &tank->getGroup(), false);
00193
00194 return tank;
00195 }