00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "Controls.h"
00010
00011 #include "Unit.h"
00012 #include "PhaseLocker.h"
00013
00014 #include "KeyStroke.h"
00015 #include "MouseStroke.h"
00016
00017
00018
00019
00020
00021
00022 Controls::Controls(PhaseLocker *locker)
00023 : m_units(), m_moves()
00024 {
00025 m_locker = locker;
00026 m_active = m_units.begin();
00027 m_speedup = 0;
00028 m_switch = true;
00029 m_strokeSymbol = ControlSym::SYM_NONE;
00030 }
00031
00032
00033
00034
00035 Controls::~Controls()
00036 {
00037 t_units::iterator end = m_units.end();
00038 for (t_units::iterator i = m_units.begin(); i != end; ++i) {
00039 delete (*i);
00040 }
00041 }
00042
00043
00044
00045
00046
00047 void
00048 Controls::addUnit(Unit *unit)
00049 {
00050 m_units.push_back(unit);
00051
00052 t_units::iterator end = m_units.end();
00053 for (t_units::iterator i = m_units.begin(); i != end; ++i) {
00054 if ((*i)->startActive()) {
00055 setActive(i);
00056 return;
00057 }
00058 }
00059 setActive(m_units.begin());
00060 }
00061
00062
00063
00064
00065 const Unit *
00066 Controls::getActive()
00067 {
00068 Unit *result = NULL;
00069 if (m_active != m_units.end()) {
00070 result = *m_active;
00071 }
00072 return result;
00073 }
00074
00075
00076
00077
00078
00079
00080
00081 bool
00082 Controls::driving(const InputProvider *input)
00083 {
00084 bool moved = false;
00085 if (!useSwitch()) {
00086 if (!useStroke()) {
00087 moved = driveUnit(input);
00088 }
00089 else {
00090 moved = true;
00091 }
00092 }
00093 return moved;
00094 }
00095
00096
00097
00098
00099 bool
00100 Controls::useSwitch()
00101 {
00102 bool result = false;
00103 if (m_active != m_units.end()) {
00104 if (!(*m_active)->willMove()) {
00105 checkActive();
00106 }
00107
00108 if (m_switch && m_active != m_units.end()) {
00109 m_locker->ensurePhases(3);
00110 (*m_active)->activate();
00111 result = true;
00112 }
00113 }
00114 m_switch = false;
00115 return result;
00116 }
00117
00118
00119
00120
00121
00122
00123 bool
00124 Controls::useStroke()
00125 {
00126 bool result = false;
00127 if (m_strokeSymbol != ControlSym::SYM_NONE) {
00128 makeMove(m_strokeSymbol);
00129 m_strokeSymbol = ControlSym::SYM_NONE;
00130 result = true;
00131 }
00132 return result;
00133 }
00134
00135 bool
00136 Controls::driveUnit(const InputProvider *input)
00137 {
00138 char moved = ControlSym::SYM_NONE;
00139 if (m_active != m_units.end()) {
00140 moved = (*m_active)->driveBorrowed(input, m_arrows);
00141 }
00142
00143 if (ControlSym::SYM_NONE == moved) {
00144 t_units::iterator end = m_units.end();
00145 for (t_units::iterator i = m_units.begin(); i != end; ++i) {
00146 moved = (*i)->drive(input);
00147 if (moved != ControlSym::SYM_NONE) {
00148 setActive(i);
00149 break;
00150 }
00151 }
00152 }
00153
00154 if (moved != ControlSym::SYM_NONE) {
00155 m_moves.push_back(moved);
00156 }
00157 return (moved != ControlSym::SYM_NONE);
00158 }
00159
00160 void
00161 Controls::lockPhases()
00162 {
00163 if (m_active != m_units.end() && (*m_active)->isMoving()) {
00164 if ((*m_active)->isPushing()) {
00165 m_speedup = 0;
00166 }
00167 else if (!(*m_active)->isTurning()) {
00168 m_speedup++;
00169 }
00170
00171 m_locker->ensurePhases(getNeededPhases(m_speedup));
00172 }
00173 else {
00174 m_speedup = 0;
00175 }
00176 }
00177
00178 int
00179 Controls::getNeededPhases(int speedup) const
00180 {
00181 static const int SPEED_WARP1 = 6;
00182 static const int SPEED_WARP2 = 10;
00183
00184 int phases = 3;
00185 if (m_active != m_units.end()) {
00186 if ((*m_active)->isTurning()) {
00187 phases = (*m_active)->countAnimPhases("turn");
00188 }
00189 else if (speedup > SPEED_WARP2) {
00190 phases = (*m_active)->countAnimPhases("swam") / 6;
00191 }
00192 else if (speedup > SPEED_WARP1) {
00193 phases = (*m_active)->countAnimPhases("swam") / 3;
00194 }
00195 else {
00196 phases = (*m_active)->countAnimPhases("swam") / 2;
00197 }
00198 }
00199 return phases;
00200 }
00201
00202
00203
00204
00205
00206 void
00207 Controls::checkActive()
00208 {
00209 if (m_active == m_units.end() || !(*m_active)->canDrive()) {
00210 switchActive();
00211 }
00212 }
00213
00214
00215
00216
00217
00218 void
00219 Controls::switchActive()
00220 {
00221 if (!m_units.empty()) {
00222 t_units::iterator start = m_active;
00223
00224 do {
00225 if (m_active == m_units.end() || m_active + 1 == m_units.end()) {
00226 m_active = m_units.begin();
00227 }
00228 else {
00229 ++m_active;
00230 }
00231 } while (m_active != start && !(*m_active)->canDrive());
00232
00233 if (start != m_active) {
00234 m_speedup = 0;
00235 m_switch = true;
00236 }
00237 }
00238 }
00239
00240
00241
00242
00243 void
00244 Controls::controlEvent(const KeyStroke &stroke)
00245 {
00246 SDLKey key = stroke.getKey();
00247
00248 if (m_strokeSymbol == ControlSym::SYM_NONE) {
00249 if (m_active != m_units.end()) {
00250 m_strokeSymbol = (*m_active)->mySymbolBorrowed(key, m_arrows);
00251 }
00252
00253 if (m_strokeSymbol == ControlSym::SYM_NONE) {
00254 t_units::iterator end = m_units.end();
00255 for (t_units::iterator i = m_units.begin(); i != end; ++i) {
00256 m_strokeSymbol = (*i)->mySymbol(key);
00257 if (m_strokeSymbol != ControlSym::SYM_NONE) {
00258 return;
00259 }
00260 }
00261 }
00262 }
00263 }
00264
00265
00266
00267
00268
00269
00270 bool
00271 Controls::activateSelected(const Cube *occupant)
00272 {
00273 t_units::iterator end = m_units.end();
00274 for (t_units::iterator i = m_units.begin(); i != end; ++i) {
00275 if ((*i)->equalsModel(occupant)) {
00276 m_active = i;
00277 m_switch = true;
00278 return true;
00279 }
00280 }
00281 return false;
00282 }
00283
00284
00285
00286
00287
00288 void
00289 Controls::setActive(t_units::iterator active)
00290 {
00291 if (m_active != active) {
00292 m_speedup = 0;
00293 m_active = active;
00294 }
00295 }
00296
00297
00298
00299
00300
00301 bool
00302 Controls::makeMove(char move)
00303 {
00304 t_units::iterator end = m_units.end();
00305 for (t_units::iterator i = m_units.begin(); i != end; ++i) {
00306 if ((*i)->driveOrder(move) == move) {
00307 setActive(i);
00308 m_moves.push_back(move);
00309 return true;
00310 }
00311 }
00312 return false;
00313 }
00314
00315
00316
00317
00318 bool
00319 Controls::cannotMove() const
00320 {
00321 t_units::const_iterator end = m_units.end();
00322 for (t_units::const_iterator i = m_units.begin(); i != end; ++i) {
00323 if ((*i)->willMove()) {
00324 return false;
00325 }
00326 }
00327 return true;
00328 }
00329
00330
00331
00332
00333 bool
00334 Controls::isPowerful() const
00335 {
00336 bool result = false;
00337 if (m_active != m_units.end()) {
00338 result = (*m_active)->isPowerful();
00339 }
00340 return result;
00341 }
00342
00343