00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <weapons/AccessoryStore.h>
00022 #include <common/RandomGenerator.h>
00023 #ifndef S3D_SERVER
00024 #include <tankgraph/TargetRendererImplTarget.h>
00025 #endif
00026 #include <target/TargetDefinition.h>
00027 #include <target/Target.h>
00028 #include <target/TargetLife.h>
00029 #include <target/TargetShield.h>
00030 #include <target/TargetParachute.h>
00031 #include <target/TargetState.h>
00032 #include <3dsparse/ModelStore.h>
00033 #include <3dsparse/Model.h>
00034 #include <common/Defines.h>
00035 #include <XML/XMLNode.h>
00036
00037 TargetDefinition::TargetDefinition() :
00038 life_(1), boundingsphere_(true),
00039 size_(0, 0, 0),
00040 modelscale_(fixed(true, 500)), modelscalediff_(0),
00041 modelrotation_(0), modelrotationsnap_(-1),
00042 driveovertodestroy_(false), flattendestroy_(false), border_(0),
00043 displaydamage_(true), displayshadow_(true), displayhardwareshadow_(true),
00044 nodamageburn_(false), nocollision_(false), nofalling_(false),
00045 nofallingdamage_(false)
00046 {
00047 shadow_.setDrawShadow(false);
00048 }
00049
00050 TargetDefinition::~TargetDefinition()
00051 {
00052 }
00053
00054 bool TargetDefinition::readXML(XMLNode *node, const char *base)
00055 {
00056 node->getNamedChild("name", name_, false);
00057 node->getNamedChild("life", life_, false);
00058 node->getNamedChild("shield", shield_, false);
00059 node->getNamedChild("parachute", parachute_, false);
00060 node->getNamedChild("boundingsphere", boundingsphere_, false);
00061 node->getNamedChild("nocollision", nocollision_, false);
00062 node->getNamedChild("nofalling", nofalling_, false);
00063 node->getNamedChild("nofallingdamage", nofallingdamage_, false);
00064 node->getNamedChild("nodamageburn", nodamageburn_, false);
00065 node->getNamedChild("displaydamage", displaydamage_, false);
00066 node->getNamedChild("displayshadow", displayshadow_, false);
00067 node->getNamedChild("displayhardwareshadow", displayhardwareshadow_, false);
00068
00069 node->getNamedChild("size", size_, false);
00070 node->getNamedChild("modelscale", modelscale_, false);
00071 node->getNamedChild("modelscalediff", modelscalediff_, false);
00072 node->getNamedChild("modelrotation", modelrotation_, false);
00073 node->getNamedChild("modelrotationsnap", modelrotationsnap_, false);
00074 node->getNamedChild("modelbrightness", modelbrightness_, false);
00075 node->getNamedChild("border", border_, false);
00076
00077 XMLNode *modelnode, *burntmodelnode;
00078 if (!node->getNamedChild("model", modelnode)) return false;
00079 if (!modelId_.initFromNode(base, modelnode)) return false;
00080 if (node->getNamedChild("modelburnt", burntmodelnode, false))
00081 {
00082 if (!modelburntId_.initFromNode(base, burntmodelnode)) return false;
00083 }
00084 else
00085 {
00086 modelnode->resurrectRemovedChildren();
00087 if (!modelburntId_.initFromNode(base, modelnode)) return false;
00088 }
00089
00090 node->getNamedChild("flattendestroy", flattendestroy_, false);
00091 node->getNamedChild("driveovertodestroy", driveovertodestroy_, false);
00092 node->getNamedChild("removeaction", removeaction_, false);
00093 node->getNamedChild("burnaction", burnaction_, false);
00094
00095 if (!shadow_.readXML(node, base)) return false;
00096 if (!groups_.readXML(node)) return false;
00097
00098 return node->failChildren();
00099 }
00100
00101 Target *TargetDefinition::createTarget(unsigned int playerId,
00102 FixedVector &position,
00103 FixedVector &velocity,
00104 ScorchedContext &context,
00105 RandomGenerator &generator)
00106 {
00107 Target *target = new Target(playerId,
00108 name_, context);
00109 target->getLife().setBoundingSphere(boundingsphere_);
00110
00111 fixed rotation = modelrotation_;
00112 if (modelrotationsnap_ > 0)
00113 {
00114 rotation = fixed((generator.getRandFixed() * 360).asInt() /
00115 (modelrotationsnap_.asInt())) * modelrotationsnap_;
00116 }
00117 fixed finalModelScale = modelscale_;
00118 if (modelscalediff_ > 0)
00119 {
00120 finalModelScale += generator.getRandFixed() * modelscalediff_;
00121 }
00122 fixed finalBrightness = modelbrightness_;
00123 if (finalBrightness == -1)
00124 {
00125 finalBrightness = generator.getRandFixed() * fixed(true, 7000) + fixed(true, 3000);
00126 }
00127
00128 FixedVector finalSize = size_;
00129 if (finalSize == FixedVector::getNullVector())
00130 {
00131 Model *model = ModelStore::instance()->loadModel(modelId_);
00132 Vector size = model->getMax() - model->getMin();
00133 finalSize = FixedVector::fromVector(size);
00134 finalSize *= finalModelScale;
00135 }
00136
00137 target->getTargetState().setNoCollision(nocollision_);
00138 target->getTargetState().setDisplayDamage(displaydamage_);
00139 target->getTargetState().setDisplayShadow(displayshadow_);
00140 target->getTargetState().setDisplayHardwareShadow(displayhardwareshadow_);
00141 target->getTargetState().setNoDamageBurn(nodamageburn_);
00142 target->getTargetState().setNoFalling(nofalling_);
00143 target->getTargetState().setNoFallingDamage(nofallingdamage_);
00144 target->getTargetState().setDriveOverToDestroy(driveovertodestroy_);
00145 target->getTargetState().setFlattenDestroy(flattendestroy_);
00146 target->getLife().setMaxLife(life_);
00147 target->getLife().setSize(finalSize);
00148 target->getLife().setVelocity(velocity);
00149 target->getLife().setRotation(rotation);
00150 target->setBorder(border_);
00151 target->newGame();
00152
00153 if (shield_.c_str()[0] && 0 != strcmp(shield_.c_str(), "none"))
00154 {
00155 Accessory *shield = context.getAccessoryStore().
00156 findByPrimaryAccessoryName(shield_.c_str());
00157 if (!shield)
00158 {
00159 S3D::dialogExit("Scorched3D",
00160 S3D::formatStringBuffer("Failed to find shield named \"%s\"",
00161 shield_.c_str()));
00162 }
00163
00164 target->getShield().setCurrentShield(shield);
00165 }
00166
00167 if (parachute_.c_str()[0] && 0 != strcmp(parachute_.c_str(), "none"))
00168 {
00169 Accessory *parachute = context.getAccessoryStore().
00170 findByPrimaryAccessoryName(parachute_.c_str());
00171 if (!parachute)
00172 {
00173 S3D::dialogExit("Scorched3D",
00174 S3D::formatStringBuffer("Failed to find parachute named \"%s\"",
00175 parachute_.c_str()));
00176 }
00177
00178 target->getParachute().setCurrentParachute(parachute);
00179 }
00180
00181 if (removeaction_.c_str()[0] && 0 != strcmp(removeaction_.c_str(), "none"))
00182 {
00183 Accessory *action = context.getAccessoryStore().
00184 findByPrimaryAccessoryName(removeaction_.c_str());
00185 if (!action || action->getType() != AccessoryPart::AccessoryWeapon)
00186 {
00187 S3D::dialogExit("Scorched3D",
00188 S3D::formatStringBuffer("Failed to find death action \"%s\"",
00189 removeaction_.c_str()));
00190 }
00191
00192 target->setDeathAction((Weapon *) action->getAction());
00193 }
00194 if (burnaction_.c_str()[0] && 0 != strcmp(burnaction_.c_str(), "none"))
00195 {
00196 Accessory *action = context.getAccessoryStore().
00197 findByPrimaryAccessoryName(burnaction_.c_str());
00198 if (!action || action->getType() != AccessoryPart::AccessoryWeapon)
00199 {
00200 S3D::dialogExit("Scorched3D",
00201 S3D::formatStringBuffer("Failed to find burn action \"%s\"",
00202 burnaction_.c_str()));
00203 }
00204
00205 target->setBurnAction((Weapon *) action->getAction());
00206 }
00207
00208 #ifndef S3D_SERVER
00209 if (!context.getServerMode())
00210 {
00211 target->setRenderer(
00212 new TargetRendererImplTarget(
00213 target, modelId_, modelburntId_,
00214 finalModelScale.asFloat(), finalBrightness.asFloat()));
00215 }
00216 #endif // #ifndef S3D_SERVER
00217
00218 target->getLife().setTargetPosition(position);
00219 groups_.addToGroups(context, &target->getGroup(), false);
00220
00221 return target;
00222 }