00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <movement/TargetMovementEntryShips.h>
00022 #include <common/Defines.h>
00023 #include <common/RandomGenerator.h>
00024 #include <engine/ScorchedContext.h>
00025 #include <target/Target.h>
00026 #include <target/TargetLife.h>
00027 #include <target/TargetState.h>
00028 #include <landscapemap/LandscapeMaps.h>
00029 #include <landscapedef/LandscapeTex.h>
00030 #include <landscapedef/LandscapeMovement.h>
00031
00032 TargetMovementEntryShips::TargetMovementEntryShips()
00033 {
00034 }
00035
00036 TargetMovementEntryShips::~TargetMovementEntryShips()
00037 {
00038 }
00039
00040 void TargetMovementEntryShips::generate(ScorchedContext &context,
00041 RandomGenerator &random, LandscapeMovementType *movementType)
00042 {
00043 int mapWidth = context.getLandscapeMaps().getGroundMaps().getLandscapeWidth();
00044 int mapHeight = context.getLandscapeMaps().getGroundMaps().getLandscapeHeight();
00045 LandscapeTex &tex = *context.getLandscapeMaps().getDefinitions().getTex();
00046
00047
00048 fixed waterHeight = 0;
00049 if (tex.border->getType() == LandscapeTexType::eWater)
00050 {
00051 LandscapeTexBorderWater *water =
00052 (LandscapeTexBorderWater *) tex.border;
00053 waterHeight = water->height;
00054 }
00055
00056
00057
00058 LandscapeMovementTypeShips *shipGroup =
00059 (LandscapeMovementTypeShips *) movementType;
00060 std::vector<FixedVector> controlPoints;
00061 controlPoints.push_back(FixedVector::getNullVector());
00062 fixed diff = fixed(360) / fixed(shipGroup->controlpoints);
00063 for (fixed i=0; i<360; i+=diff)
00064 {
00065 fixed distWidth = random.getRandFixed() *
00066 shipGroup->controlpointsrand + shipGroup->controlpointswidth;
00067 fixed distHeight = random.getRandFixed() *
00068 shipGroup->controlpointsrand + shipGroup->controlpointsheight;
00069 fixed x = (i / 180 * fixed::XPI).sin() * distWidth + fixed(mapWidth) / 2;
00070 fixed y = (i / 180 * fixed::XPI).cos() * distHeight + fixed(mapHeight) / 2;
00071
00072 FixedVector pt(x,y,waterHeight);
00073 controlPoints.push_back(pt);
00074 }
00075
00076
00077 FixedVector midPt = (controlPoints[1] + controlPoints.back()) / 2;
00078 controlPoints.push_back(midPt);
00079 controlPoints.front() = midPt;
00080
00081
00082 path_.generate(controlPoints, 200, 3, shipGroup->speed);
00083 path_.simulate(shipGroup->starttime);
00084
00085
00086 groupEntry_ = context.getLandscapeMaps().getGroundMaps().getGroups().
00087 getGroup(shipGroup->groupname.c_str());
00088 if (!groupEntry_)
00089 {
00090 S3D::dialogExit("TargetMovementEntryShips",
00091 S3D::formatStringBuffer("Group entry %s has no objects defined for it",
00092 shipGroup->groupname.c_str()));
00093 }
00094
00095
00096 std::map<unsigned int, TargetGroup *> &objects = groupEntry_->getObjects();
00097 std::map<unsigned int, TargetGroup *>::iterator itor;
00098 for (itor = objects.begin();
00099 itor != objects.end();
00100 itor++)
00101 {
00102 unsigned int playerId = (*itor).first;
00103 TargetGroup *entry = (*itor).second;
00104
00105 if (!entry->getTarget()->isTarget() ||
00106 entry->getTarget()->getPlayerId() >= TargetID::MIN_TARGET_TRANSIENT_ID)
00107 {
00108 S3D::dialogExit("TargetMovementEntryShips",
00109 "Movement can be assigned to level targets only (no tanks)");
00110 }
00111 if (entry->getTarget()->getTargetState().getMovement())
00112 {
00113 S3D::dialogExit("TargetMovementEntryBoids",
00114 "Only one movement can be assigned to each target");
00115 }
00116
00117
00118 fixed offX = random.getRandFixed() * 200;
00119 fixed offY = random.getRandFixed() * 200;
00120 FixedVector offset(offX, offY - 100, 0);
00121 TargetMovementEntryShipsOffset *offsetEntry = new TargetMovementEntryShipsOffset();
00122 offsetEntry->offset = offset;
00123
00124
00125 entry->getTarget()->getTargetState().setMovement(offsetEntry);
00126 }
00127 }
00128
00129 void TargetMovementEntryShips::simulate(ScorchedContext &context, fixed frameTime)
00130 {
00131
00132 path_.simulate(frameTime);
00133
00134
00135 FixedVector position;
00136 FixedVector direction;
00137 path_.getPathAttrs(position, direction);
00138 FixedVector directionPerp = direction.get2DPerp();
00139
00140
00141 std::map<unsigned int, TargetGroup *> &objects = groupEntry_->getObjects();
00142 std::map<unsigned int, TargetGroup *>::iterator itor;
00143 for (itor = objects.begin();
00144 itor != objects.end();
00145 itor++)
00146 {
00147 unsigned int playerId = (*itor).first;
00148 TargetGroup *groupEntry = (*itor).second;
00149
00150 TargetMovementEntryShipsOffset *offsetEntry = (TargetMovementEntryShipsOffset *)
00151 groupEntry->getTarget()->getTargetState().getMovement();
00152 if (offsetEntry)
00153 {
00154
00155 FixedVector &offset = offsetEntry->offset;
00156 FixedVector shipPosition = position;
00157 shipPosition += directionPerp * -offset[0];
00158 shipPosition += direction * offset[1];
00159 shipPosition[2] -= 1;
00160 fixed angle = atan2x(direction[1], direction[0]);
00161 fixed angleDegs = (angle / fixed::XPI) * 180 - 90;
00162
00163
00164 groupEntry->getTarget()->getLife().setTargetPositionAndRotation(
00165 position, angleDegs);
00166 }
00167 }
00168 }
00169
00170 bool TargetMovementEntryShips::writeMessage(NetBuffer &buffer)
00171 {
00172 fixed pathTime = path_.getPathTime();
00173 buffer.addToBuffer(pathTime);
00174 return true;
00175 }
00176
00177 bool TargetMovementEntryShips::readMessage(NetBufferReader &reader)
00178 {
00179 fixed pathTime = 0;
00180 if (!reader.getFromBuffer(pathTime)) return false;
00181 path_.setPathTime(pathTime);
00182 return true;
00183 }
00184
00185 void TargetMovementEntryShips::draw()
00186 {
00187 #ifndef S3D_SERVER
00188 path_.draw();
00189 #endif
00190 }