Public Member Functions | |
bool | Hit () const |
void | DetectLoop (const gHitData &hit, gLoopData loopData[2]) |
gAISensor (const gCycle *c, const eCoord &start, const eCoord &dir, REAL sideScan, REAL frontScan, REAL corridorScan, int winding) | |
Public Attributes | |
const gCycle * | cycle |
bool | hit |
gHitData | front |
gHitData | sides [2] |
gLoopData | frontLoop [2] |
gLoopData | sideLoop [2][2] |
REAL | distance |
Definition at line 657 of file gAIBase.cpp.
gAISensor::gAISensor | ( | const gCycle * | c, | |
const eCoord & | start, | |||
const eCoord & | dir, | |||
REAL | sideScan, | |||
REAL | frontScan, | |||
REAL | corridorScan, | |||
int | winding | |||
) | [inline] |
Definition at line 748 of file gAIBase.cpp.
References ai, AI_LOOP, AI_RANGE, AI_TUNNEL, gAIPlayer::Character(), eSensor::detect(), eDebugLine::Draw(), eCoord, fabsf(), eSensor::hit, eNetGameObject::Player(), gAICharacter::properties, Random(), REAL, eDebugLine::SetColor(), eDebugLine::SetTimeout(), tASSERT, and eGameObject::Team().
00755 :cycle(c), distance(frontScan*2) 00756 { 00757 gAIPlayer* ai = dynamic_cast<gAIPlayer*>(c->Player()); 00758 tASSERT(ai); 00759 gAICharacter* character = ai->Character(); 00760 tASSERT(character); 00761 00762 hit = false; 00763 00764 eDebugLine::SetTimeout(.5); 00765 00766 gCycle* cycle = const_cast<gCycle*>( this->cycle ); 00767 00768 // detect straight ahead 00769 gSensor ahead(cycle, start, dir); 00770 00771 int count = 0; 00772 00773 do{ 00774 ahead.detect(frontScan); 00775 front.AddHit(start, dir, ahead, winding); 00776 if (front.Hit()) 00777 { 00778 hit = true; 00779 distance = front.distance; 00780 if (character->properties[AI_LOOP] > 3 + fabsf(winding) * 3) 00781 DetectLoop(front, frontLoop); 00782 } 00783 } while (!front.Hit() && count++ < character->properties[AI_RANGE]); 00784 00785 // adapt the corridor distance so the corridor is not looked for too far away 00786 if (distance*.99f < corridorScan) 00787 corridorScan = distance * .99f; 00788 corridorScan -= sideScan * .02; 00789 if (corridorScan < 0.1f) 00790 corridorScan = 0.1f; 00791 00792 if (Random() * 10 < character->properties[AI_TUNNEL]) 00793 { 00794 // check the sides 00795 eCoord lookTunnel = start + dir * corridorScan; 00796 00797 int i; 00798 00799 for (i = 1; i>=0; i--) 00800 { 00801 int lr = i+i-1; 00802 eCoord lrDir = dir.Turn(eCoord(.01f, -lr)); 00803 00804 gSensor side(cycle, start, lrDir); 00805 side.detect(sideScan*1.01f); 00806 REAL thisSideScan = side.hit*.99f; 00807 00808 gSensor tunnel(cycle, lookTunnel, lrDir); 00809 tunnel.detect(thisSideScan); 00810 sides[i].AddHit(start, dir, tunnel, winding + lr); 00811 00812 gSensor parallel(cycle, start + lrDir * thisSideScan, dir); 00813 parallel.detect(corridorScan); 00814 sides[i].AddHit(start, dir, parallel, winding); 00815 00816 if (sides[i].Hit()) 00817 { 00818 if (character->properties[AI_LOOP] > 6 + fabsf(winding) * 3) 00819 DetectLoop(sides[i], sideLoop[i]); 00820 00821 if (sideLoop[i][1-i].loop || 00822 (character->properties[AI_TUNNEL] >= 10 && 00823 sides[i].otherCycle && 00824 sides[i].otherCycle->Team() != cycle->Team() && 00825 sides[i].lr * (i+i-1) < 0 && 00826 sides[i].otherCycle->GetDistance() < sides[i].driveDistance + sides[i].otherCycle->Speed() * 20) 00827 ) 00828 { 00829 if (sides[i].distance < distance) 00830 distance = sides[i].distance; 00831 00832 hit = true; 00833 } 00834 } 00835 00836 #ifdef DEBUG_X 00837 { 00838 gRandomController noRandom; 00839 gSensor ahead(cycle, start, dir); 00840 ahead.detect(frontScan); 00841 00842 gSensor side(cycle, start, lrDir); 00843 side.detect(sideScan*1.01f); 00844 REAL thisSideScan = side.hit*.99f; 00845 00846 gSensor tunnel(cycle, lookTunnel, lrDir); 00847 tunnel.detect(thisSideScan); 00848 // sides[i].AddHit(start, dir, tunnel, winding + lr); 00849 00850 gSensor parallel(cycle, start + lrDir * thisSideScan, dir); 00851 parallel.detect(corridorScan); 00852 // sides[i].AddHit(start, dir, parallel, winding); 00853 } 00854 #endif 00855 00856 } 00857 } 00858 if (sides[1].otherCycle == sides[0].otherCycle && sides[0].otherCycle) 00859 hit = true; 00860 00861 #ifdef DEBUGLINE 00862 if (Hit()) 00863 { 00864 eDebugLine::SetColor (1, 1, 1); 00865 eDebugLine::SetTimeout(1); 00866 eDebugLine::Draw(start, .5, start + dir*distance, .5); 00867 00868 eDebugLine::SetColor (1, .5, 1); 00869 eDebugLine::Draw(start + dir*distance, .5, start + dir*distance, 1.5); 00870 } 00871 #endif 00872 00873 eDebugLine::SetTimeout(0); 00874 00875 }
bool gAISensor::Hit | ( | ) | const [inline] |
Definition at line 674 of file gAIBase.cpp.
Referenced by gAIPlayer::EmergencySurvive(), gAIPlayer::Think(), gAIPlayer::ThinkCloseCombat(), and gAIPlayer::ThinkTrace().
00675 { 00676 return hit; 00677 }
Definition at line 679 of file gAIBase.cpp.
References CheckLoop(), gLoopData::closedIn, gHitData::driveDistance, gLoopData::loop, gHitData::lr, gHitData::otherCycle, REAL, tArray< T, MALLOC >::SetLen(), gLoopData::winding, and gHitData::windingNumber.
00680 { 00681 // avoid loops: 00682 gCycle *other = hit.otherCycle; 00683 00684 if (other) 00685 { 00686 // if (other!= Object()) 00687 { 00688 REAL dist = hit.driveDistance; 00689 int otherSide = hit.lr < 0 ? 0 : 1; 00690 for (int i=1; i>=0; i--) 00691 { 00692 loopData[i].closedIn.SetLen(0); 00693 loopData[i].loop = false; 00694 00695 int lr = i+i-1; 00696 int dir = hit.lr * lr > 0 ? 1 : 0; 00697 int winding = 0; 00698 bool loop = CheckLoop(cycle, other, 00699 dist, otherSide, dir, 00700 loopData[i].closedIn, winding); 00701 00702 if (loop) 00703 { 00704 // complete the winding calculation: the target winding 00705 // is the one of this cycle: 00706 winding += cycle->WindingNumber(); 00707 // and the source is the winding of the wall we hit 00708 winding -= hit.windingNumber; 00709 00710 // if (dir == 0) 00711 // winding -= lr * (Object()->Grid()->WindingNumber() >> 1); 00712 00713 winding += lr; 00714 00715 #ifdef DEBUG_X 00716 if (winding != 4 && winding != -4) 00717 { 00718 gRandomController noRandom; 00719 if (winding != 0) 00720 // st_Breakpoint(); 00721 00722 winding = 0; 00723 CheckLoop(cycle, other, 00724 dist, otherSide, dir, 00725 loopData[i].closedIn, winding); 00726 00727 winding += cycle->WindingNumber(); 00728 winding -= hit.windingNumber; 00729 winding += lr; 00730 } 00731 #endif 00732 00733 #ifdef DEBUG 00734 // con << "winding = " << winding << " ,direction = " << lr << "\n"; 00735 #endif 00736 // if the winding continues the direction we would turn in, 00737 // we're trapped. 00738 if (winding * lr > 0) 00739 loopData[i].loop = true; 00740 00741 loopData[i].winding = winding; 00742 } 00743 } 00744 } 00745 } 00746 }
const gCycle* gAISensor::cycle |
Definition at line 661 of file gAIBase.cpp.
bool gAISensor::hit |
Definition at line 663 of file gAIBase.cpp.
Definition at line 665 of file gAIBase.cpp.
Referenced by gAIPlayer::EmergencySurvive(), gAIPlayer::ThinkSurvive(), and gAIPlayer::ThinkTrace().
Definition at line 666 of file gAIBase.cpp.
gLoopData gAISensor::sideLoop[2][2] |
Definition at line 672 of file gAIBase.cpp.
Referenced by gAIPlayer::EmergencySurvive(), sg_GetSensor(), gAIPlayer::Think(), gAIPlayer::ThinkCloseCombat(), gAIPlayer::ThinkPath(), and gAIPlayer::ThinkTrace().