00001 /* 00002 * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net) 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 */ 00009 #include "Unit.h" 00010 00011 #include "Cube.h" 00012 #include "Rules.h" 00013 #include "InputProvider.h" 00014 #include "Anim.h" 00015 #include "Shape.h" 00016 00017 #include <assert.h> 00018 00019 //----------------------------------------------------------------- 00020 /** 00021 * Create new driveable unit. 00022 * @param buttons control buttons 00023 * @param symbols move symbols stored in load/save 00024 * @param a_startActive whether unit should be active at start 00025 */ 00026 Unit::Unit(const KeyControl &buttons, const ControlSym &symbols, 00027 bool a_startActive) 00028 : m_buttons(buttons), m_symbols(symbols) 00029 { 00030 m_model = NULL; 00031 m_startActive = a_startActive; 00032 } 00033 //----------------------------------------------------------------- 00034 bool 00035 Unit::canDrive() const 00036 { 00037 return m_model->isAlive() 00038 && !m_model->isLost() 00039 && !m_model->isBusy(); 00040 } 00041 //----------------------------------------------------------------- 00042 /** 00043 * Return true when we can move in future. 00044 */ 00045 bool 00046 Unit::willMove() const 00047 { 00048 return m_model->isAlive() 00049 && !m_model->isLost(); 00050 } 00051 //----------------------------------------------------------------- 00052 /** 00053 * Test keys and try move. 00054 * @return a symbol when unit has moved 00055 */ 00056 char 00057 Unit::drive(const InputProvider *input) 00058 { 00059 return driveBorrowed(input, m_buttons); 00060 } 00061 //----------------------------------------------------------------- 00062 /** 00063 * Test keys and try move, use borrowed controls. 00064 * @return a symbol when unit has moved or SYM_NONE 00065 */ 00066 char 00067 Unit::driveBorrowed(const InputProvider *input, const KeyControl &buttons) 00068 { 00069 if (canDrive()) { 00070 if (input->isPressed(buttons.getLeft())) { 00071 return goLeft(); 00072 } 00073 if (input->isPressed(buttons.getRight())) { 00074 return goRight(); 00075 } 00076 if (input->isPressed(buttons.getUp())) { 00077 return goUp(); 00078 } 00079 if (input->isPressed(buttons.getDown())) { 00080 return goDown(); 00081 } 00082 } 00083 return ControlSym::SYM_NONE; 00084 } 00085 //----------------------------------------------------------------- 00086 /** 00087 * Greet the player. 00088 */ 00089 void 00090 Unit::activate() 00091 { 00092 m_model->rules()->actionActivate(); 00093 } 00094 //----------------------------------------------------------------- 00095 /** 00096 * Translate this key to symbol. 00097 * @return symbol or SYM_NONE for unknown key 00098 */ 00099 char 00100 Unit::mySymbol(SDLKey key) const 00101 { 00102 return mySymbolBorrowed(key, m_buttons); 00103 } 00104 //----------------------------------------------------------------- 00105 /** 00106 * Translate this key to symbol, compare with borrowed buttons. 00107 * @return symbol or SYM_NONE for unknown key 00108 */ 00109 char 00110 Unit::mySymbolBorrowed(SDLKey key, const KeyControl &buttons) const 00111 { 00112 if (key == buttons.getLeft()) { 00113 return m_symbols.getLeft(); 00114 } 00115 if (key == buttons.getRight()) { 00116 return m_symbols.getRight(); 00117 } 00118 if (key == buttons.getUp()) { 00119 return m_symbols.getUp(); 00120 } 00121 if (key == buttons.getDown()) { 00122 return m_symbols.getDown(); 00123 } 00124 return ControlSym::SYM_NONE; 00125 } 00126 //----------------------------------------------------------------- 00127 /** 00128 * Returns symbol for this direction. 00129 */ 00130 char 00131 Unit::myOrder(Dir::eDir dir) const 00132 { 00133 switch (dir) { 00134 case Dir::DIR_LEFT: 00135 return m_symbols.getLeft(); 00136 case Dir::DIR_RIGHT: 00137 return m_symbols.getRight(); 00138 case Dir::DIR_UP: 00139 return m_symbols.getUp(); 00140 case Dir::DIR_DOWN: 00141 return m_symbols.getDown(); 00142 default: 00143 assert(!"unknown dir"); 00144 } 00145 return ControlSym::SYM_NONE; 00146 } 00147 //----------------------------------------------------------------- 00148 /** 00149 * Make move. 00150 * @return move symbol or SYM_NONE for bad move 00151 */ 00152 char 00153 Unit::driveOrder(char move) 00154 { 00155 if (canDrive()) { 00156 if (m_symbols.getLeft() == move) { 00157 return goLeft(); 00158 } 00159 if (m_symbols.getRight() == move) { 00160 return goRight(); 00161 } 00162 if (m_symbols.getUp() == move) { 00163 return goUp(); 00164 } 00165 if (m_symbols.getDown() == move) { 00166 return goDown(); 00167 } 00168 } 00169 return ControlSym::SYM_NONE; 00170 } 00171 //----------------------------------------------------------------- 00172 char 00173 Unit::goLeft() 00174 { 00175 char symbol = ControlSym::SYM_NONE; 00176 if (m_model->isLeft()) { 00177 if (m_model->rules()->actionMoveDir(Dir::DIR_LEFT)) { 00178 symbol = m_symbols.getLeft(); 00179 } 00180 } 00181 else { 00182 m_model->rules()->actionTurnSide(); 00183 symbol = m_symbols.getLeft(); 00184 } 00185 return symbol; 00186 } 00187 //----------------------------------------------------------------- 00188 char 00189 Unit::goRight() 00190 { 00191 char symbol = ControlSym::SYM_NONE; 00192 if (!m_model->isLeft()) { 00193 if (m_model->rules()->actionMoveDir(Dir::DIR_RIGHT)) { 00194 symbol = m_symbols.getRight(); 00195 } 00196 } 00197 else { 00198 m_model->rules()->actionTurnSide(); 00199 symbol = m_symbols.getRight(); 00200 } 00201 return symbol; 00202 } 00203 //----------------------------------------------------------------- 00204 char 00205 Unit::goUp() 00206 { 00207 char symbol = ControlSym::SYM_NONE; 00208 if (m_model->rules()->actionMoveDir(Dir::DIR_UP)) { 00209 symbol = m_symbols.getUp(); 00210 } 00211 return symbol; 00212 } 00213 //----------------------------------------------------------------- 00214 char 00215 Unit::goDown() 00216 { 00217 char symbol = ControlSym::SYM_NONE; 00218 if (m_model->rules()->actionMoveDir(Dir::DIR_DOWN)) { 00219 symbol = m_symbols.getDown(); 00220 } 00221 return symbol; 00222 } 00223 00224 //----------------------------------------------------------------- 00225 bool 00226 Unit::isMoving() const 00227 { 00228 bool result = false; 00229 if (canDrive()) { 00230 std::string action = m_model->rules()->getAction(); 00231 result = action == "move_left" || action == "move_right" 00232 || action == "move_up" || action == "move_down" 00233 || action == "turn"; 00234 } 00235 return result; 00236 } 00237 //----------------------------------------------------------------- 00238 bool 00239 Unit::isTurning() const 00240 { 00241 std::string action = m_model->rules()->getAction(); 00242 return action == "turn"; 00243 } 00244 //----------------------------------------------------------------- 00245 bool 00246 Unit::isPushing() const 00247 { 00248 return m_model->rules()->getState() == "pushing"; 00249 } 00250 //----------------------------------------------------------------- 00251 /** 00252 * Returns true when models are equal. 00253 */ 00254 bool 00255 Unit::equalsModel(const Cube *other) const 00256 { 00257 return m_model == other; 00258 } 00259 //----------------------------------------------------------------- 00260 V2 00261 Unit::getLoc() const 00262 { 00263 return m_model->getLocation(); 00264 } 00265 //----------------------------------------------------------------- 00266 int 00267 Unit::getW() const 00268 { 00269 return m_model->shape()->getW(); 00270 } 00271 //----------------------------------------------------------------- 00272 int 00273 Unit::getH() const 00274 { 00275 return m_model->shape()->getH(); 00276 } 00277 //----------------------------------------------------------------- 00278 bool 00279 Unit::isFreePlace(const V2 &loc) const 00280 { 00281 return m_model->const_rules()->isFreePlace(loc); 00282 } 00283 //----------------------------------------------------------------- 00284 int 00285 Unit::countAnimPhases(const std::string &anim) const 00286 { 00287 return m_model->anim()->countAnimPhases(anim); 00288 } 00289 //----------------------------------------------------------------- 00290 bool 00291 Unit::isPowerful() const { 00292 return m_model->getPower() >= Cube::HEAVY; 00293 } 00294