00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <landscapedef/LandscapeSound.h>
00022 #include <landscapemap/LandscapeMaps.h>
00023 #ifndef S3D_SERVER
00024 #include <landscape/Landscape.h>
00025 #include <graph/MainCamera.h>
00026 #include <sound/Sound.h>
00027 #include <water/Water.h>
00028 #include <client/ScorchedClient.h>
00029 #endif
00030 #include <target/Target.h>
00031 #include <target/TargetLife.h>
00032 #include <common/Defines.h>
00033 #include <math.h>
00034
00035 bool LandscapeSoundPositionSet::readXML(XMLNode *node)
00036 {
00037 if (!node->getNamedChild("name", name)) return false;
00038 if (!node->getNamedChild("maxsounds", maxsounds)) return false;
00039
00040 return node->failChildren();
00041 }
00042
00043 bool LandscapeSoundPositionSet::setPosition(VirtualSoundSource *source, unsigned int data)
00044 {
00045 #ifndef S3D_SERVER
00046 TargetGroupsGroupEntry *groupEntry =
00047 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getGroups().getGroup(
00048 name.c_str());
00049 if (!groupEntry) return false;
00050 if (groupEntry->getObjectCount() <= 0) return false;
00051
00052 TargetGroup *obj = groupEntry->getObjectById(data);
00053 if (!obj) return false;
00054
00055 Vector position = obj->getPosition().asVector();
00056 Vector velocity = obj->getTarget()->getLife().getVelocity().asVector();
00057 source->setPosition(position);
00058 source->setVelocity(velocity);
00059 #endif
00060
00061 return true;
00062 }
00063
00064 int LandscapeSoundPositionSet::getInitCount()
00065 {
00066 #ifndef S3D_SERVER
00067 TargetGroupsGroupEntry *groupEntry =
00068 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getGroups().getGroup(
00069 name.c_str());
00070 if (groupEntry) return (MIN(maxsounds, groupEntry->getObjectCount()));
00071 #endif
00072
00073 return 0;
00074 }
00075
00076 unsigned int LandscapeSoundPositionSet::getInitData(int count)
00077 {
00078 #ifndef S3D_SERVER
00079 TargetGroupsGroupEntry *groupEntry =
00080 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getGroups().getGroup(
00081 name.c_str());
00082 if (groupEntry)
00083 {
00084 unsigned int playerId = groupEntry->getObjectByPos(count)->getTarget()->getPlayerId();
00085 return playerId;
00086 }
00087 #endif
00088
00089 return 0;
00090 }
00091
00092 bool LandscapeSoundPositionGroup::readXML(XMLNode *node)
00093 {
00094 if (!node->getNamedChild("falloff", falloff)) return false;
00095 if (!node->getNamedChild("name", name)) return false;
00096 return node->failChildren();
00097 }
00098
00099 bool LandscapeSoundPositionGroup::setPosition(VirtualSoundSource *source, unsigned int data)
00100 {
00101 #ifndef S3D_SERVER
00102 Vector &cameraPos =
00103 MainCamera::instance()->getCamera().getCurrentPos();
00104 int groundMapWidth = ScorchedClient::instance()->
00105 getLandscapeMaps().getGroundMaps().getLandscapeWidth();
00106 int groundMapHeight = ScorchedClient::instance()->
00107 getLandscapeMaps().getGroundMaps().getLandscapeHeight();
00108
00109 int a = int(cameraPos[0]);
00110 int b = int(cameraPos[1]);
00111 int x = MAX(0, MIN(a, groundMapWidth));
00112 int y = MAX(0, MIN(b, groundMapHeight));
00113
00114 float distance = 255.0f;
00115 TargetGroupsGroupEntry *groupEntry =
00116 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getGroups().getGroup(
00117 name.c_str());
00118 if (groupEntry)
00119 {
00120 if (groupEntry->getObjectCount() <= 0) return false;
00121
00122 distance = groupEntry->getDistance(x, y);
00123 }
00124 distance += fabsf(float(a - x)) + fabsf(float(b - y));
00125 distance *= 4.0f * falloff;
00126
00127 Vector position(0.0f, 0.0f, distance + cameraPos[2]);
00128
00129 source->setRelative();
00130 source->setPosition(position);
00131 #endif
00132
00133 return true;
00134 }
00135
00136 bool LandscapeSoundPositionWater::readXML(XMLNode *node)
00137 {
00138 if (!node->getNamedChild("falloff", falloff)) return false;
00139 return node->failChildren();
00140 }
00141
00142 bool LandscapeSoundPositionWater::setPosition(VirtualSoundSource *source, unsigned int data)
00143 {
00144 #ifndef S3D_SERVER
00145 Vector &cameraPos =
00146 MainCamera::instance()->getCamera().getCurrentPos();
00147
00148 float distance = Landscape::instance()->getWater().
00149 getWaveDistance(int(cameraPos[0]), int(cameraPos[1]));
00150 distance *= 4.0f * falloff;
00151
00152 Vector position(0.0f, 0.0f, distance + cameraPos[2]);
00153
00154 source->setRelative();
00155 source->setPosition(position);
00156 #endif
00157
00158 return true;
00159 }
00160
00161 bool LandscapeSoundPositionAmbient::readXML(XMLNode *node)
00162 {
00163 return node->failChildren();
00164 }
00165
00166 bool LandscapeSoundPositionAmbient::setPosition(VirtualSoundSource *source, unsigned int data)
00167 {
00168 #ifndef S3D_SERVER
00169 source->setRelative();
00170 source->setPosition(Vector::getNullVector());
00171 #endif
00172
00173 return true;
00174 }
00175
00176 bool LandscapeSoundPositionAbsoulte::readXML(XMLNode *node)
00177 {
00178 if (!node->getNamedChild("position", position)) return false;
00179 return node->failChildren();
00180 }
00181
00182 bool LandscapeSoundPositionAbsoulte::setPosition(VirtualSoundSource *source, unsigned int data)
00183 {
00184 #ifndef S3D_SERVER
00185 source->setPosition(position);
00186 #endif
00187 return true;
00188 }
00189
00190 bool LandscapeSoundTimingLooped::readXML(XMLNode *node)
00191 {
00192 return node->failChildren();
00193 }
00194
00195 float LandscapeSoundTimingLooped::getNextEventTime()
00196 {
00197 return -1.0f;
00198 }
00199
00200 bool LandscapeSoundTimingRepeat::readXML(XMLNode *node)
00201 {
00202 if (!node->getNamedChild("min", min)) return false;
00203 if (!node->getNamedChild("max", max)) return false;
00204 return node->failChildren();
00205 }
00206
00207 float LandscapeSoundTimingRepeat::getNextEventTime()
00208 {
00209 return min + max * RAND;
00210 }
00211
00212 bool LandscapeSoundSoundFile::readXML(XMLNode *node)
00213 {
00214 std::string file;
00215 while (node->getNamedChild("file", file, false))
00216 {
00217 if (!S3D::checkDataFile(file.c_str())) return false;
00218 files.push_back(file);
00219 }
00220 if (files.empty()) return node->returnError("No file node");
00221
00222 gain = 1.0f;
00223 node->getNamedChild("gain", gain, false);
00224 referencedistance = 75.0f;
00225 node->getNamedChild("referencedistance", referencedistance, false);
00226 rolloff = 1.0f;
00227 node->getNamedChild("rolloff", rolloff, false);
00228
00229 return node->failChildren();
00230 }
00231
00232 bool LandscapeSoundSoundFile::play(VirtualSoundSource *source)
00233 {
00234 #ifndef S3D_SERVER
00235 std::string &file = files[rand() % files.size()];
00236 SoundBuffer *buffer =
00237 Sound::instance()->fetchOrCreateBuffer(
00238 S3D::getDataFile(file.c_str()));
00239 if (!buffer) return false;
00240
00241 source->setGain(gain);
00242 source->setRolloff(rolloff);
00243 source->setReferenceDistance(referencedistance);
00244 source->play(buffer);
00245 #endif
00246
00247 return true;
00248 }
00249
00250 LandscapeSoundType::LandscapeSoundType() :
00251 position(0), timing(0), sound(0)
00252 {
00253 }
00254
00255 LandscapeSoundType::~LandscapeSoundType()
00256 {
00257 delete position;
00258 delete timing;
00259 delete sound;
00260 }
00261
00262 bool LandscapeSoundType::readXML(XMLNode *node)
00263 {
00264 {
00265 std::string soundtype;
00266 XMLNode *soundNode;
00267 if (!node->getNamedChild("sound", soundNode)) return false;
00268 if (!soundNode->getNamedParameter("type", soundtype)) return false;
00269 if (0 == strcmp(soundtype.c_str(), "file"))
00270 sound = new LandscapeSoundSoundFile;
00271 else return false;
00272
00273 if (!sound->readXML(soundNode)) return false;
00274 }
00275
00276 {
00277 std::string positiontype;
00278 XMLNode *positionNode;
00279 if (!node->getNamedChild("position", positionNode)) return false;
00280 if (!positionNode->getNamedParameter("type", positiontype)) return false;
00281 if (0 == strcmp(positiontype.c_str(), "ambient"))
00282 position = new LandscapeSoundPositionAmbient;
00283 else if (0 == strcmp(positiontype.c_str(), "absolute"))
00284 position = new LandscapeSoundPositionAbsoulte;
00285 else if (0 == strcmp(positiontype.c_str(), "water"))
00286 position = new LandscapeSoundPositionWater;
00287 else if (0 == strcmp(positiontype.c_str(), "group"))
00288 position = new LandscapeSoundPositionGroup;
00289 else if (0 == strcmp(positiontype.c_str(), "set"))
00290 position = new LandscapeSoundPositionSet;
00291 else return false;
00292 if (!position->readXML(positionNode)) return false;
00293 }
00294 {
00295 std::string timingtype;
00296 XMLNode *timingNode;
00297 if (!node->getNamedChild("timing", timingNode)) return false;
00298 if (!timingNode->getNamedParameter("type", timingtype)) return false;
00299 if (0 == strcmp(timingtype.c_str(), "looped"))
00300 timing = new LandscapeSoundTimingLooped;
00301 else if (0 == strcmp(timingtype.c_str(), "repeat"))
00302 timing = new LandscapeSoundTimingRepeat;
00303 else return false;
00304 if (!timing->readXML(timingNode)) return false;
00305 }
00306 return node->failChildren();
00307 }