//--------------------------------------------------------------------------- long SoundSystem::playDigitalSample (unsigned long sampleId, Stuff::Vector3D pos, bool allowDupes) { if (useSound && allowDupes || (!isPlayingSample(sampleId) && !allowDupes)) { if (sampleId >= numSoundBites) return(-1); long ourChannel = findOpenChannel(1,SUPPORT_CHANNEL); if (ourChannel != -1) { float distanceVolume = 1.0f; float panVolume = 0.0f; if (eye && (pos.z != -9999.0f)) { Stuff::Vector3D distance; distance.Subtract(eye->getPosition(),pos); float dist = distance.GetApproximateLength(); if (dist < FALLOFF_DISTANCE) distanceVolume = (FALLOFF_DISTANCE - dist) / FALLOFF_DISTANCE; else return -1; //Do not play sound. TOO far away!! //Figure out where in stereo field to play. OppRotate(distance,eye->getRotation().y); panVolume = distance.x / (FALLOFF_DISTANCE * 0.5f); if (panVolume > 1.0f) panVolume = 1.0f; else if (panVolume < -1.0f) panVolume = -1.0f; } float vol = sounds[sampleId].volume * distanceVolume; if (vol > 1.0f) vol = 1.0f; else if (vol <= 0.0f) //No VOlume. DON't PLAY! return -1; gosAudio_SetChannelSlider(ourChannel,gosAudio_Panning, panVolume); gosAudio_SetChannelSlider(ourChannel,gosAudio_Volume, (digitalMasterVolume * vol * SFXVolume)) ; channelSampleId[ourChannel] = sampleId; channelInUse[ourChannel] = TRUE; if (sounds[sampleId].biteData && sounds[sampleId].resourceHandle) { gosAudio_AssignResourceToChannel( ourChannel, sounds[sampleId].resourceHandle ); gosAudio_SetChannelPlayMode(ourChannel, gosAudio_PlayOnce); } return(ourChannel); } } return(-1); }
//--------------------------------------------------------------------------- void Terrain::geometry (void) { //--------------------------------------------------------------------- leastZ = 1.0f;leastW = 1.0f; mostZ = -1.0f; mostW = -1.0; leastWY = 0.0f; mostWY = 0.0f; //----------------------------------- // Transform entire list of vertices VertexPtr currentVertex = vertexList; Stuff::Vector3D cameraPos; cameraPos.x = -eye->getCameraOrigin().x; cameraPos.y = eye->getCameraOrigin().z; cameraPos.z = eye->getCameraOrigin().y; float vClipConstant = eye->verticalSphereClipConstant; float hClipConstant = eye->horizontalSphereClipConstant; long i=0; for (i=0;i<numberVertices;i++) { //---------------------------------------------------------------------------------------- // Figure out if we are in front of camera or not. Should be faster then actual project! // Should weed out VAST overwhelming majority of vertices! bool onScreen = false; //----------------------------------------------------------------- // Find angle between lookVector of Camera and vector from camPos // to Target. If angle is less then halfFOV, object is visible. if (eye->usePerspective) { //------------------------------------------------------------------- //NEW METHOD from the WAY BACK Days onScreen = true; Stuff::Vector3D vPosition; vPosition.x = currentVertex->vx; vPosition.y = currentVertex->vy; vPosition.z = currentVertex->pVertex->elevation; Stuff::Vector3D objectCenter; objectCenter.Subtract(vPosition,cameraPos); Camera::cameraFrame.trans_to_frame(objectCenter); float distanceToEye = objectCenter.GetApproximateLength(); Stuff::Vector3D clipVector = objectCenter; clipVector.z = 0.0f; float distanceToClip = clipVector.GetApproximateLength(); float clip_distance = fabs(1.0f / objectCenter.y); if (distanceToClip > CLIP_THRESHOLD_DISTANCE) { //Is vertex on Screen OR close enough to screen that its triangle MAY be visible? // WE have removed the atans here by simply taking the tan of the angle we want above. float object_angle = fabs(objectCenter.z) * clip_distance; float extent_angle = VERTEX_EXTENT_RADIUS / distanceToEye; if (object_angle > (vClipConstant + extent_angle)) { //In theory, we would return here. Object is NOT on screen. onScreen = false; } else { object_angle = fabs(objectCenter.x) * clip_distance; if (object_angle > (hClipConstant + extent_angle)) { //In theory, we would return here. Object is NOT on screen. onScreen = false; } } } if (onScreen) { if (distanceToEye > Camera::MaxClipDistance) { currentVertex->hazeFactor = 1.0f; } else if (distanceToEye > Camera::MinHazeDistance) { currentVertex->hazeFactor = (distanceToEye - Camera::MinHazeDistance) * Camera::DistanceFactor; } else { currentVertex->hazeFactor = 0.0f; } //--------------------------------------- // Vertex is at edge of world or beyond. Stuff::Vector3D vPos(currentVertex->vx,currentVertex->vy,currentVertex->pVertex->elevation); bool isVisible = Terrain::IsGameSelectTerrainPosition(vPos) || drawTerrainGrid; if (!isVisible) { currentVertex->hazeFactor = 1.0f; onScreen = true; } } else { currentVertex->hazeFactor = 1.0f; } } else { currentVertex->hazeFactor = 0.0f; onScreen = true; } bool inView = false; Stuff::Vector4D screenPos(-10000.0f,-10000.0f,-10000.0f,-10000.0f); if (onScreen) { Stuff::Vector3D vertex3D(currentVertex->vx,currentVertex->vy,currentVertex->pVertex->elevation); inView = eye->projectZ(vertex3D,screenPos); currentVertex->px = screenPos.x; currentVertex->py = screenPos.y; currentVertex->pz = screenPos.z; currentVertex->pw = screenPos.w; //---------------------------------------------------------------------------------- //We must transform these but should NOT draw any face where all three are fogged. // if (currentVertex->hazeFactor == 1.0f) // onScreen = false; } else { currentVertex->px = currentVertex->py = 10000.0f; currentVertex->pz = -0.5f; currentVertex->pw = 0.5f; currentVertex->hazeFactor = 0.0f; } //------------------------------------------------------------ // Fix clip. Vertices can all be off screen and triangle // still needs to be drawn! if (eye->usePerspective && Environment.Renderer != 3) { currentVertex->clipInfo = onScreen; } else currentVertex->clipInfo = inView; if (currentVertex->clipInfo) //ONLY set TRUE ones. Otherwise we just reset the FLAG each vertex! { setObjBlockActive(currentVertex->getBlockNumber(), true); setObjVertexActive(currentVertex->vertexNum,true); if (inView) { if (screenPos.z < leastZ) { leastZ = screenPos.z; } if (screenPos.z > mostZ) { mostZ = screenPos.z; } if (screenPos.w < leastW) { leastW = screenPos.w; leastWY = screenPos.y; } if (screenPos.w > mostW) { mostW = screenPos.w; mostWY = screenPos.y; } } } currentVertex++; } //----------------------------------- // setup terrain quad textures // Also sets up mine data. TerrainQuadPtr currentQuad = quadList; for (i=0;i<numberQuads;i++) { currentQuad->setupTextures(); currentQuad++; } float ywRange = 0.0f, yzRange = 0.0f; if (fabs(mostWY - leastWY) > Stuff::SMALL) { ywRange = (mostW - leastW) / (mostWY - leastWY); yzRange = (mostZ - leastZ) / (mostWY - leastWY); } eye->setInverseProject(mostZ,leastW,yzRange,ywRange); //----------------------------------- // update the cloud layer if (Terrain::cloudLayer) Terrain::cloudLayer->update(); }
//--------------------------------------------------------------------------- bool Team::lineOfSight(float startLocal, int32_t mCellRow, int32_t mCellCol, int32_t tCellRow, int32_t tCellCol, int32_t teamId, float extRad, bool checkVisibleBits) { #ifdef LAB_ONLY int64_t x = GetCycles(); #endif //----------------------------------------------------- // Once we allow teams to have alliances (for contacts, // etc.), simply set all nec. team bits in this mask... //TILE HACK... int32_t tileRow = tCellRow / 3; int32_t tileCol = tCellCol / 3; if((teamId < 0) || (teamId >= MAX_TEAMS)) //Not on any team. It can see everything! return true; if(checkVisibleBits) { uint8_t teamMask = 0x01 << teamId; uint8_t visbBits[4]; //---------------------------------------------------------------------------- // First check is simple. Is anyone within the magical line of sight radius? // If not, return false and move on. // If they are, you MUST check LOS between this object and the other one. bool losResult = false; visbBits[0] = Terrain::VisibleBits->getFlag(tileRow, tileCol); if(visbBits[0] & teamMask) losResult = true; if(!losResult) { visbBits[1] = Terrain::VisibleBits->getFlag(tileRow + 1, tileCol); if(visbBits[1] & teamMask) losResult = true; } if(!losResult) { visbBits[2] = Terrain::VisibleBits->getFlag(tileRow + 1, tileCol + 1); if(visbBits[2] & teamMask) losResult = true; } if(!losResult) { visbBits[3] = Terrain::VisibleBits->getFlag(tileRow, tileCol + 1); if(visbBits[3] & teamMask) losResult = true; } if(!losResult) { #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif return losResult; } } if(useRealLOS) { //------------------------------------------------------------------------------------------ // Within magic radius. Check REAL LOS now. // Check is really simple. // Find deltaCellRow and deltaCellCol and iterate over them from source to dest. // If the magic line ever goes BELOW the terrainElevation PLUS localElevation return false. Stuff::Vector3D startPos, endPos; startPos.Zero(); endPos.Zero(); land->getCellPos(tCellRow, tCellCol, endPos); land->getCellPos(mCellRow, mCellCol, startPos); startPos.z += startLocal; Stuff::Vector3D deltaCellVec; deltaCellVec.y = tCellRow - mCellRow; deltaCellVec.x = tCellCol - mCellCol; deltaCellVec.z = 0.0f; float startHeight = startPos.z; float length = deltaCellVec.GetApproximateLength(); if(length > Stuff::SMALL) { float colLength = deltaCellVec.x / length; float rowLength = deltaCellVec.y / length; float heightLen = (endPos.z - startPos.z) / length; float lastCol = fabs(colLength * 2.0); float lastRow = fabs(rowLength * 2.0); float startCellRow = mCellRow; float startCellCol = mCellCol; float endCellRow = tCellRow; float endCellCol = tCellCol; Stuff::Vector3D currentPos = startPos; Stuff::Vector3D dist; dist.Subtract(endPos, currentPos); float remainingDist = dist.GetApproximateLength(); bool colDone = false, rowDone = false; while(!colDone || !rowDone) { if(fabs(startCellRow - endCellRow) > lastRow) //DO NOT INCLUDE LAST CELL!!!!! { startCellRow += rowLength; } else { // startCellRow = (endCellRow - lastRow); rowDone = true; } if(fabs(startCellCol - endCellCol) > lastCol) //DO NOT INCLUDE LAST CELL!!!!! { startCellCol += colLength; } else { // startCellCol = (endCellCol - lastCol); colDone = true; } startHeight += heightLen; int32_t startCellC = startCellCol; int32_t startCellR = startCellRow; land->getCellPos(startCellR, startCellC, currentPos); float localElev = (worldUnitsPerMeter * 4.0f * (float)GameMap->getLocalHeight(startCellR, startCellC)); currentPos.z += localElev; if(startHeight + startLocal < currentPos.z) { #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif #ifdef LAB_ONLY if(drawTerrainGrid) { Stuff::Vector3D realStart = startPos; Stuff::Vector4D lineStart, lineEnd; eye->projectZ(realStart, lineStart); eye->projectZ(endPos, lineEnd); debugLines[currentLineElement++] = new LineElement(lineStart, lineEnd, SD_RED, nullptr, -1); } #endif return false; } if(extRad > Stuff::SMALL) { dist.Subtract(endPos, currentPos); remainingDist = dist.GetApproximateLength(); if(remainingDist < extRad) break; } } } #ifdef LAB_ONLY if(drawTerrainGrid) { Stuff::Vector3D realStart = startPos; Stuff::Vector4D lineStart, lineEnd; eye->projectZ(realStart, lineStart); eye->projectZ(endPos, lineEnd); debugLines[currentLineElement++] = new LineElement(lineStart, lineEnd, SD_GREEN, nullptr, -1); } #endif } #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif return true; }
//--------------------------------------------------------------------------- bool Team::teamLineOfSight(Stuff::Vector3D tPos, float extRad) { //----------------------------------------------------------- // For each member of the team, check LOS to point provided. for(size_t i = 0; i < rosterSize; i++) { MoverPtr obj = (MoverPtr)ObjectManager->getByWatchID(roster[i]); if(!obj->isDisabled() && !obj->isDestroyed() && (obj->getStatus() != OBJECT_STATUS_SHUTDOWN)) { Stuff::Vector3D distance; distance.Subtract(tPos, obj->getPosition()); float dist = distance.GetApproximateLength(); //Figure out altitude above minimum terrain altitude and look up in table. float baseElevation = MapData::waterDepth; if(MapData::waterDepth < Terrain::userMin) baseElevation = Terrain::userMin; float altitude = obj->getPosition().z - baseElevation; float altitudeIntegerRange = (Terrain::userMax - baseElevation) * 0.00390625f; int32_t altLevel = 0; if(altitudeIntegerRange > Stuff::SMALL) altLevel = altitude / altitudeIntegerRange; if(altLevel < 0) altLevel = 0; if(altLevel > 255) altLevel = 255; float radius = visualRangeTable[altLevel]; //Scouting specialty skill. if(obj->isMover()) { MoverPtr mover = (MoverPtr)obj; if(mover->pilot && mover->pilot->isScout()) radius += (radius * 0.2f); radius *= mover->getLOSFactor(); } if(dist <= (radius * 25.0f * worldUnitsPerMeter)) { if(lineOfSight(obj->getLOSPosition(), tPos, id, extRad, 0.0f, false)) return true; } } } //------------------------------------------------------------------------- // Check the lookout towers now. You can find them in special Buildings!! for(size_t spBuilding = 0; spBuilding < ObjectManager->numSpecialBuildings; spBuilding++) { if(ObjectManager->specialBuildings[spBuilding] && ObjectManager->specialBuildings[spBuilding]->getExists() && ObjectManager->specialBuildings[spBuilding]->isLookoutTower() && (ObjectManager->specialBuildings[spBuilding]->getTeamId() == id)) { GameObjectPtr obj = ObjectManager->specialBuildings[spBuilding]; if(!obj->isDisabled() && !obj->isDestroyed() && (obj->getStatus() != OBJECT_STATUS_SHUTDOWN)) { Stuff::Vector3D distance; distance.Subtract(tPos, obj->getPosition()); float dist = distance.GetApproximateLength(); //Figure out altitude above minimum terrain altitude and look up in table. float baseElevation = MapData::waterDepth; if(MapData::waterDepth < Terrain::userMin) baseElevation = Terrain::userMin; float altitude = obj->getPosition().z - baseElevation; float altitudeIntegerRange = (Terrain::userMax - baseElevation) * 0.00390625f; int32_t altLevel = 0; if(altitudeIntegerRange > Stuff::SMALL) altLevel = altitude / altitudeIntegerRange; if(altLevel < 0) altLevel = 0; if(altLevel > 255) altLevel = 255; float radius = visualRangeTable[altLevel]; //Scouting specialty skill. if(obj->isMover()) { MoverPtr mover = (MoverPtr)obj; if(mover->pilot && mover->pilot->isScout()) radius += (radius * 0.2f); radius *= mover->getLOSFactor(); } if(dist <= (radius * 25.0f * worldUnitsPerMeter)) { if(lineOfSight(obj->getLOSPosition(), tPos, id, 0.0f, obj->getAppearRadius(), false)) return true; } } } } return false; }
//--------------------------------------------------------------------------- bool Team::lineOfSight(float startLocal, int32_t mCellRow, int32_t mCellCol, float endLocal, int32_t tCellRow, int32_t tCellCol, int32_t teamId, float extRad, float startExtRad, bool checkVisibleBits) { #ifdef LAB_ONLY int64_t x = GetCycles(); #endif //----------------------------------------------------- // Once we allow teams to have alliances (for contacts, // etc.), simply set all nec. team bits in this mask... //TILE HACK... int32_t tileRow = tCellRow / 3; int32_t tileCol = tCellCol / 3; if((teamId < 0) || (teamId >= MAX_TEAMS)) //Not on any team. It can see everything! return true; #if 0 //Don't need to check this anymore. We do a distance check outside of this function. if(checkVisibleBits) { uint8_t teamMask = 0x01 << teamId; uint8_t visbBits[4]; //---------------------------------------------------------------------------- // First check is simple. Is anyone within the magical line of sight radius? // If not, return false and move on. // If they are, you MUST check LOS between this object and the other one. bool losResult = false; visbBits[0] = Terrain::VisibleBits->getFlag(tileRow, tileCol); if(visbBits[0] & teamMask) losResult = true; if(!losResult) { visbBits[1] = Terrain::VisibleBits->getFlag(tileRow + 1, tileCol); if(visbBits[1] & teamMask) losResult = true; } if(!losResult) { visbBits[2] = Terrain::VisibleBits->getFlag(tileRow + 1, tileCol + 1); if(visbBits[2] & teamMask) losResult = true; } if(!losResult) { visbBits[3] = Terrain::VisibleBits->getFlag(tileRow, tileCol + 1); if(visbBits[3] & teamMask) losResult = true; } if(!losResult) { #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif return losResult; } } #endif if(useRealLOS) { //------------------------------------------------------------------------------------------ // Within magic radius. Check REAL LOS now. // Check is really simple. // Find deltaCellRow and deltaCellCol and iterate over them from source to dest. // If the magic line ever goes BELOW the terrainElevation PLUS localElevation return false. Stuff::Vector3D startPos, endPos; startPos.Zero(); endPos.Zero(); land->getCellPos(tCellRow, tCellCol, endPos); land->getCellPos(mCellRow, mCellCol, startPos); startPos.z += startLocal; endPos.z += endLocal; Stuff::Vector3D deltaCellVec; deltaCellVec.y = tCellRow - mCellRow; deltaCellVec.x = tCellCol - mCellCol; deltaCellVec.z = 0.0f; float startHeight = startPos.z; float length = deltaCellVec.GetApproximateLength(); length *= ACCURACY_ADJUST; if(length > Stuff::SMALL) { float colLength = (endPos.x - startPos.x) / length; float rowLength = (endPos.y - startPos.y) / length; float heightLen = (endPos.z - startPos.z) / (length + ACCURACY_ADJUST); Stuff::Vector3D currentPos = startPos; currentPos.z = land->getTerrainElevation(currentPos); int32_t maxDistIter = (length - 0.5f); int32_t maxTrees = 0; Stuff::Vector3D dist; dist.Subtract(endPos, currentPos); float remainingDist = dist.GetApproximateLength(); bool checkExtent = (extRad > Stuff::SMALL); bool checkStart = (startExtRad > Stuff::SMALL); extRad += HALF_CELL_DIST; for(size_t distIter = 0; distIter < maxDistIter; distIter++) { bool outsideStartRadius = true; if(checkStart) { Stuff::Vector3D distance; distance.Subtract(currentPos, startPos); distance.z = 0.0f; float dist = distance.GetApproximateLength(); if(dist <= startExtRad) outsideStartRadius = false; } startHeight += heightLen; int32_t curCellRow, curCellCol; land->worldToCell(currentPos, curCellRow, curCellCol); float localElev = (worldUnitsPerMeter * 4.0f * (float)GameMap->getLocalHeight(curCellRow, curCellCol)); float thisHeight = currentPos.z + localElev; //First, check if we are now inside the extent radius of the thing we are calcing LOS to. // If we are and we haven't returned false since we're here, we can see it!!!! if(checkExtent) { dist.Subtract(endPos, currentPos); remainingDist = dist.GetApproximateLength(); if(remainingDist <= extRad) break; } if(outsideStartRadius && (startHeight < thisHeight)) { bool isTree = false; if(GameMap->getForest(curCellRow, curCellCol)) { maxTrees++; isTree = true; } if(!isTree || (maxTrees >= MaxTreeLOSCellBlock)) { #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif #ifdef LAB_ONLY if(drawTerrainGrid) { Stuff::Vector3D realStart = startPos; Stuff::Vector4D lineStart, lineEnd; eye->projectZ(realStart, lineStart); eye->projectZ(endPos, lineEnd); debugLines[currentLineElement++] = new LineElement(lineStart, lineEnd, SD_RED, nullptr, -1); } #endif return false; } } currentPos.x += colLength; currentPos.y += rowLength; currentPos.z = land->getTerrainElevation(currentPos); } } #ifdef LAB_ONLY if(drawTerrainGrid) { Stuff::Vector3D realStart = startPos; Stuff::Vector4D lineStart, lineEnd; eye->projectZ(realStart, lineStart); eye->projectZ(endPos, lineEnd); debugLines[currentLineElement++] = new LineElement(lineStart, lineEnd, SD_GREEN, nullptr, -1); } #endif } #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif return true; }
//--------------------------------------------------------------------------- int32_t Building::updateAnimations(void) { //--------------------------------------------- // Animate Sensor Towers first. /* if (sensorSystem != nullptr) { int32_t animState = appearance->getCurrentGestureId(); if (sensorSystem->numContacts) { switch (animState) { case -1: //NOT UPDATED YET. SWITCH TO ZERO if (!appearance->getInTransition()) { appearance->setGesture(0); } break; case 2: //Just Animating. Do NOTHING! break; case 0: //Not triggered yet. Switch to 1 appearance->setGesture(1); break; case 1: //triggered, when fully open switch to 2 if (!appearance->getInTransition()) { appearance->setGesture(2); } break; case 3: //Closing. Wait until closed and then switch to 1. if (!appearance->getInTransition()) { appearance->setGesture(1); } break; } } else //This will be handled by sensor system going disabled if building destroyed OR parent destroyed! { switch (animState) { case -1: //NOT UPDATED YET. SWITCH TO ZERO if (!appearance->getInTransition()) { appearance->setGesture(0); } break; case 2: //Just Animating. Wait until one loop done, then trigger closing if (!appearance->getInTransition()) { appearance->setGesture(3); } break; case 0: //Not triggered yet. DO NOTHING! break; case 1: //triggered, when fully open switch to 3 to close it. if (!appearance->getInTransition()) { appearance->setGesture(3); } break; case 3: //Closing to closed. When Closed, DO NOTHING break; } } } else*/ if(((BuildingTypePtr)getObjectType())->resourcePoints) { if(!MPlayer) { //We are a resource Points Building. //OPEN when we have been CAPTURED!! int32_t animState = appearance->getCurrentGestureId(); if(!teamId) //We've been Captured { switch(animState) { case -1: //NOT UPDATED YET. SWITCH TO ZERO if(!appearance->getInTransition()) { appearance->setGesture(0); } break; case 2: //Just Animating. Do NOTHING! break; case 0: //Not triggered yet. Switch to 1 appearance->setGesture(1); break; case 1: //triggered, when fully open switch to 2 if(!appearance->getInTransition()) { appearance->setGesture(2); } break; case 3: //Closing. Wait until closed and then switch to 1. if(!appearance->getInTransition()) { appearance->setGesture(1); } break; } } else { //Stay Closed switch(animState) { case -1: //NOT UPDATED YET. SWITCH TO ZERO if(!appearance->getInTransition()) { appearance->setGesture(0); } break; case 2: //Just Animating. Do NOTHING! break; case 0: //Do Nothing break; case 1: //triggered, when fully open switch to 3 if(!appearance->getInTransition()) { appearance->setGesture(3); } break; case 3: //Closing. Wait until closed and then switch to 1. if(!appearance->getInTransition()) { appearance->setGesture(0); } break; } } } } else if(((BuildingTypePtr)getObjectType())->mechBay) { if(!MPlayer) { //We are a Mech Repair Bay Building. // Open to the correct place based on our RepairBuddyWID int32_t animState = appearance->getCurrentGestureId(); if(!refitBuddyWID) //We're repairing no one. { switch(animState) { case -1: //NOT UPDATED YET. SWITCH TO ZERO if(!appearance->getInTransition()) { appearance->setGesture(0); } break; case 1: //We were repairing someone. Switch to doing nothing! if(!appearance->getInTransition()) { appearance->setGesture(5); } break; case 2: //We were repairing someone. Switch to doing nothing! if(!appearance->getInTransition()) { appearance->setGesture(6); } break; case 3: //We were repairing someone. Switch to doing nothing! if(!appearance->getInTransition()) { appearance->setGesture(7); } break; case 4: //We were repairing someone. Switch to doing nothing! if(!appearance->getInTransition()) { appearance->setGesture(8); } break; case 5: //We were repairing someone. Switch to doing nothing! case 6: //We were repairing someone. Switch to doing nothing! case 7: //We were repairing someone. Switch to doing nothing! case 8: //We were repairing someone. Switch to doing nothing! if(!appearance->getInTransition()) { appearance->setGesture(0); } break; case 0: //Do Nothing. We aren't repairing anyone break; } } else { //We are repairing someone. switch(animState) { case -1: //NOT UPDATED YET. SWITCH TO ZERO if(!appearance->getInTransition()) { appearance->setGesture(0); } break; case 1: case 2: case 3: case 4: //DO NOTHING!! We are in position. { GameObjectPtr refitMech = ObjectManager->getByWatchID(refitBuddyWID); if(refitMech && (refitMech->getStatus() == OBJECT_STATUS_SHUTDOWN)) { if(((BuildingTypePtr)getObjectType())->activityEffectId != 0xffffffff) appearance->startActivity(((BuildingTypePtr)getObjectType())->activityEffectId, true); } else { appearance->stopActivity(); } } break; case 0: if(!appearance->getInTransition()) { GameObjectPtr refitMech = ObjectManager->getByWatchID(refitBuddyWID); if(refitMech) { Stuff::Vector3D distance; distance.Subtract(refitMech->getPosition(), getPosition()); float dist = distance.GetApproximateLength(); if(dist <= 128.0f) { if(refitMech && (refitMech->getTonnage() <= 40.0f)) { appearance->setGesture(1); } else if(refitMech && (refitMech->getTonnage() <= 60.0f)) { appearance->setGesture(2); } else if(refitMech && (refitMech->getTonnage() <= 80.0f)) { appearance->setGesture(3); } else if(refitMech && (refitMech->getTonnage() <= 100.0f)) { appearance->setGesture(4); } } } } break; case 5: //We were repairing someone. Switch to doing nothing! case 6: //We were repairing someone. Switch to doing nothing! case 7: //We were repairing someone. Switch to doing nothing! case 8: //We were repairing someone. Switch to doing nothing! if(!appearance->getInTransition()) { appearance->setGesture(0); } break; } } } else //MechBays must ALWAYS be open in Mplayer or it will look dumb! { appearance->setGesture(4); } } else { //Just about everything else animates here. if(!isDisabled() && !isDestroyed()) { if(!appearance->getInTransition()) { appearance->setGesture(0); } } else //This will be handled by building destroyed OR parent destroyed! { } } return 0; }