1 /* $Id: simplebot.cpp,v 1.5 2005/10/16 17:53:05 pohlt Exp $ */
2 
3 #include "simplebot.hpp"
4 #include "avatar.hpp"
5 #include "global.hpp"
6 #include <vector>
7 
SimpleBot()8 SimpleBot::SimpleBot()
9 	: m_event( Event::EMPTY ), m_count( 0 ) {
10 }
11 
update()12 void SimpleBot::update() {
13 	Vector position = m_avatar->getPos();
14 	std::vector<Object*> visibleObjects = m_avatar->getVisibleObjects();
15 
16 	// always keep moving
17 	if ( position == m_lastPosition ) {
18 		if ( m_count > 5 ) {
19 			m_count = 0;
20 			// try digging
21 			if ( !m_event.testAnyActions( Event::DIG ) ) {
22 				INFO( "SimpleBot: start digging\n" );
23 				m_event.addAction( Event::DIG );
24 			}
25 			else {
26 				// turn around and stop digging
27 				if ( m_event.testAnyActions( Event::LEFT ) ) {
28 					INFO( "SimpleBot: turn right\n" );
29 					m_event.removeAction( Event::LEFT );
30 					m_event.addAction( Event::RIGHT );
31 				}
32 				else {
33 					INFO( "SimpleBot: turn left\n" );
34 					m_event.removeAction( Event::RIGHT );
35 					m_event.addAction( Event::LEFT );
36 				}
37 				INFO( "SimpleBot: stop digging\n" );
38 				m_event.removeAction( Event::DIG );
39 			}
40 		}
41 		else
42 			m_count++;
43 	}
44 	m_lastPosition = position;
45 
46 	// aim to the nearest adversary avatar visible
47 	Avatar* nearestAvatar = 0;
48 	real nearestDistance = 0.0;
49 	for ( unsigned int i = 0; i < visibleObjects.size(); i++ ) {
50 		Object* object = visibleObjects[i];
51 		if ( object->isAvatar() ) {
52 			Avatar* avatar = dynamic_cast<Avatar*>( object );
53 			if ( avatar && avatar->getPlayer()->getPlayerOrTeamID() !=
54 			               m_avatar->getPlayer()->getPlayerOrTeamID() ) {
55 				real distance = (avatar->getPos() - m_avatar->getPos()).abs();
56 				if ( !nearestAvatar || distance < nearestDistance ) {
57 					nearestAvatar = avatar;
58 					nearestDistance = distance;
59 				}
60 			}
61 		}
62 	}
63 
64 	if ( nearestAvatar ) {
65 		// yes, we found an enemy
66 		// turn to the side where the enemy is located
67 		if ( nearestAvatar->getPosX() > m_avatar->getPosX() ) {
68 			m_event.removeAction( Event::LEFT );
69 			m_event.addAction( Event::RIGHT );
70 		}
71 		else if ( nearestAvatar->getPosX() < m_avatar->getPosX() ) {
72 			m_event.removeAction( Event::RIGHT );
73 			m_event.addAction( Event::LEFT );
74 		}
75 
76 		// adjust aiming angle
77 		real enemyAngle =
78 			ATAN2_REAL( ( nearestAvatar->getPosY() - m_avatar->getPosY() ),
79 			            ( nearestAvatar->getPosX() - m_avatar->getPosX() ) )
80 			* 180.0 / M_PI + 90.0;
81 		INFO( "own angle = %f, enemy angle = %f\n", m_avatar->getAimingAngle(), enemyAngle );
82 		if ( enemyAngle < m_avatar->getAimingAngle() ) {
83 			INFO( "Aiming up\n" );
84 			m_event.removeAction( Event::DOWN );
85 			m_event.addAction( Event::UP );
86 		}
87 		else if ( enemyAngle > m_avatar->getAimingAngle() ) {
88 			INFO( "Aiming down\n" );
89 			m_event.removeAction( Event::UP );
90 			m_event.addAction( Event::DOWN );
91 		}
92 
93 		// shoot whenever possible
94 		if ( getActiveWeapon()->getCurrentAmmo() == 0 ) {
95 			m_event.removeAction( Event::SHOOT );
96 			if ( getActiveWeaponIndex() == 0 )
97 				m_event.setWeapon( 2 );
98 			else
99 				m_event.setWeapon( 1 );
100 		}
101 		else {
102 			m_event.addAction( Event::SHOOT );
103 		}
104 	}
105 
106 	// respawn if dead
107 	if ( !m_avatar->isLiving() ) {
108 		INFO( "SimpleBot: respawn\n" );
109 		m_event.addAction( Event::SPAWN );
110 	}
111 	else
112 		m_event.removeAction( Event::SPAWN );
113 
114 	INFO( "Bot event = %x\n", m_event.get() );
115 }
116