00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <tankgraph/TankKeyboardControlUtil.h>
00022 #include <tank/Tank.h>
00023 #include <tank/TankPosition.h>
00024 #include <tank/TankState.h>
00025 #include <tank/TankAccessories.h>
00026 #include <tankgraph/TargetRendererImplTank.h>
00027 #include <target/TargetShield.h>
00028 #include <target/TargetLife.h>
00029 #include <coms/ComsMessageSender.h>
00030 #include <coms/ComsPlayedMoveMessage.h>
00031 #include <coms/ComsDefenseMessage.h>
00032 #include <client/ScorchedClient.h>
00033 #include <client/ClientState.h>
00034 #include <weapons/AccessoryStore.h>
00035 #include <common/Keyboard.h>
00036 #include <common/Line.h>
00037 #include <landscapemap/LandscapeMaps.h>
00038 #include <graph/OptionsDisplay.h>
00039 #include <graph/MainCamera.h>
00040 #include <sound/Sound.h>
00041
00042 VirtualSoundSource *TankKeyboardControlUtil::elevateSound_(0);
00043 VirtualSoundSource *TankKeyboardControlUtil::rotateSound_(0);
00044 VirtualSoundSource *TankKeyboardControlUtil::startSound_(0);
00045 VirtualSoundSource *TankKeyboardControlUtil::powerSound_(0);
00046
00047 TankKeyboardControlUtil::TankKeyboardControlUtil()
00048 {
00049 }
00050
00051 TankKeyboardControlUtil::~TankKeyboardControlUtil()
00052 {
00053 }
00054
00055 void TankKeyboardControlUtil::keyboardCheck(
00056 Tank *tank,
00057 const unsigned state,
00058 float frameTime, char *buffer,
00059 unsigned int keyState)
00060 {
00061
00062 if (!elevateSound_) elevateSound_ =
00063 new VirtualSoundSource(VirtualSoundPriority::eRotation, true, false);
00064 elevateSound_->setPosition(tank->getPosition().getTankPosition().asVector());
00065 if (!rotateSound_) rotateSound_ =
00066 new VirtualSoundSource(VirtualSoundPriority::eRotation, true, false);
00067 rotateSound_->setPosition(tank->getPosition().getTankPosition().asVector());
00068 if (!startSound_) startSound_ =
00069 new VirtualSoundSource(VirtualSoundPriority::eRotation, false, false);
00070 startSound_->setPosition(tank->getPosition().getTankPosition().asVector());
00071 if (!powerSound_) powerSound_ =
00072 new VirtualSoundSource(VirtualSoundPriority::eRotation, true, false);
00073 powerSound_->setPosition(tank->getPosition().getTankPosition().asVector());
00074
00075
00076 moveLeftRight(tank, buffer, keyState, frameTime);
00077 moveUpDown(tank, buffer, keyState, frameTime);
00078 movePower(tank, buffer, keyState, frameTime);
00079
00080 KEYBOARDKEY("FIRE_WEAPON", fireKey);
00081 if (fireKey->keyDown(buffer, keyState, false))
00082 {
00083
00084
00085 Accessory *currentWeapon =
00086 tank->getAccessories().getWeapons().getCurrent();
00087 if (currentWeapon &&
00088 currentWeapon->getPositionSelect() == Accessory::ePositionSelectNone)
00089 {
00090 fireShot(tank);
00091 }
00092 }
00093
00094 KEYBOARDKEY("AUTO_AIM", aimKey);
00095 if (aimKey->keyDown(buffer, keyState))
00096 {
00097 autoAim(tank);
00098 }
00099
00100 KEYBOARDKEY("ENABLE_PARACHUTES", parachuteKey);
00101 if (parachuteKey->keyDown(buffer, keyState, false))
00102 {
00103 std::list<Accessory *> ¶chutes =
00104 tank->getAccessories().getAllAccessoriesByType(
00105 AccessoryPart::AccessoryParachute);
00106 if (parachutes.size() == 1)
00107 {
00108 parachutesUpDown(tank, parachutes.front()->getAccessoryId());
00109 }
00110 }
00111
00112 KEYBOARDKEY("ENABLE_SHIELDS", shieldKey);
00113 if (shieldKey->keyDown(buffer, keyState, false))
00114 {
00115 if (!tank->getShield().getCurrentShield())
00116 {
00117 std::list<Accessory *> &shields =
00118 tank->getAccessories().getAllAccessoriesByType(
00119 AccessoryPart::AccessoryShield);
00120 if (shields.size() == 1)
00121 {
00122 shieldsUpDown(tank, shields.front()->getAccessoryId());
00123 }
00124 }
00125 }
00126
00127 KEYBOARDKEY("USE_BATTERY", batteryKey);
00128 if (batteryKey->keyDown(buffer, keyState, false))
00129 {
00130 if (tank->getLife().getLife() <
00131 tank->getLife().getMaxLife())
00132 {
00133 std::list<Accessory *> &entries =
00134 tank->getAccessories().getAllAccessoriesByType(
00135 AccessoryPart::AccessoryBattery);
00136 if (!entries.empty())
00137 {
00138 useBattery(tank, entries.front()->getAccessoryId());
00139 }
00140 }
00141 }
00142
00143 KEYBOARDKEY("UNDO_MOVE", undoKey);
00144 if (undoKey->keyDown(buffer, keyState, false))
00145 {
00146 tank->getPosition().undo();
00147 }
00148
00149 KEYBOARDKEY("CHANGE_UP_WEAPON", weaponUpKey);
00150 KEYBOARDKEY("CHANGE_DOWN_WEAPON", weaponDownKey);
00151 bool upWeapon = weaponUpKey->keyDown(buffer, keyState, false);
00152 bool downWeapon = weaponDownKey->keyDown(buffer, keyState, false);
00153 if (upWeapon || downWeapon)
00154 {
00155 if (downWeapon)
00156 {
00157 prevWeapon(tank);
00158 }
00159 else
00160 {
00161 nextWeapon(tank);
00162 }
00163
00164 TargetRendererImplTankHUD::setText("Weapon : ",
00165 tank->getAccessories().getWeapons().getWeaponString());
00166 }
00167 }
00168
00169 void TankKeyboardControlUtil::nextWeapon(Tank *tank)
00170 {
00171 std::list<Accessory *> &result =
00172 tank->getAccessories().getAllAccessoriesByType(
00173 AccessoryPart::AccessoryWeapon);
00174 ScorchedClient::instance()->getAccessoryStore().sortList(result,
00175 OptionsDisplay::instance()->getAccessorySortKey());
00176
00177 std::list<Accessory *>::iterator itor;
00178 for (itor = result.begin();
00179 itor != result.end();
00180 itor++)
00181 {
00182 if (tank->getAccessories().getWeapons().getCurrent() == (*itor))
00183 {
00184 if (++itor == result.end())
00185 {
00186 itor = result.begin();
00187 }
00188 tank->getAccessories().getWeapons().setWeapon(*itor);
00189 break;
00190 }
00191 }
00192 }
00193
00194 void TankKeyboardControlUtil::prevWeapon(Tank *tank)
00195 {
00196 std::list<Accessory *> &result =
00197 tank->getAccessories().getAllAccessoriesByType(
00198 AccessoryPart::AccessoryWeapon);
00199 ScorchedClient::instance()->getAccessoryStore().sortList(result,
00200 OptionsDisplay::instance()->getAccessorySortKey());
00201
00202 std::list<Accessory *>::iterator itor;
00203 for (itor = result.begin();
00204 itor != result.end();
00205 itor++)
00206 {
00207 if (tank->getAccessories().getWeapons().getCurrent() == (*itor))
00208 {
00209 if (itor == result.begin())
00210 {
00211 itor = result.end();
00212 }
00213
00214 --itor;
00215 tank->getAccessories().getWeapons().setWeapon(*itor);
00216 break;
00217 }
00218 }
00219 }
00220
00221 void TankKeyboardControlUtil::endPlayMove(Tank *tank)
00222 {
00223 if (elevateSound_) elevateSound_->stop();
00224 if (rotateSound_) rotateSound_->stop();
00225 if (powerSound_) powerSound_->stop();
00226 }
00227
00228 void TankKeyboardControlUtil::autoAim(Tank *tank)
00229 {
00230 int x = ScorchedClient::instance()->getGameState().getMouseX();
00231 int y = ScorchedClient::instance()->getGameState().getMouseY();
00232 Line direction;
00233 Vector intersect;
00234
00235 MainCamera::instance()->getCamera().draw();
00236 if (MainCamera::instance()->getCamera().
00237 getDirectionFromPt((GLfloat) x, (GLfloat) y, direction))
00238 {
00239 if (ScorchedClient::instance()->getLandscapeMaps().
00240 getGroundMaps().getIntersect(direction, intersect))
00241 {
00242 Vector &position = tank->getPosition().getTankPosition().asVector();
00243
00244
00245 Vector direction = intersect - position;
00246 float angleXYRads = atan2f(direction[1], direction[0]);
00247 float angleXYDegs = (angleXYRads / 3.14f) * 180.0f - 90.0f;
00248
00249 tank->getPosition().rotateGunXY(fixed::fromFloat(angleXYDegs), false);
00250 leftRightHUD(tank);
00251
00252 TargetRendererImplTankAIM::setAimPosition(intersect);
00253 }
00254 }
00255 }
00256
00257 void TankKeyboardControlUtil::moveLeftRight(Tank *tank,
00258 char *buffer, unsigned int keyState, float frameTime)
00259 {
00260 static bool LRMoving = false;
00261 bool currentLRMoving = false;
00262
00263 KEYBOARDKEY("TURN_RIGHT", rightKey);
00264 KEYBOARDKEY("TURN_RIGHT_SLOW", rightSlowKey);
00265 KEYBOARDKEY("TURN_RIGHT_VSLOW", rightVSlowKey);
00266 KEYBOARDKEY("TURN_RIGHT_FAST", rightFastKey);
00267 KEYBOARDKEY("TURN_LEFT", leftKey);
00268 KEYBOARDKEY("TURN_LEFT_SLOW", leftSlowKey);
00269 KEYBOARDKEY("TURN_LEFT_VSLOW", leftVSlowKey);
00270 KEYBOARDKEY("TURN_LEFT_FAST", leftFastKey);
00271
00272 bool rightK = rightKey->keyDown(buffer, keyState);
00273 bool rightKF = rightFastKey->keyDown(buffer, keyState);
00274 bool rightKS = rightSlowKey->keyDown(buffer, keyState);
00275 bool rightKVS = rightVSlowKey->keyDown(buffer, keyState);
00276 bool leftK = leftKey->keyDown(buffer, keyState);
00277 bool leftKF = leftFastKey->keyDown(buffer, keyState);
00278 bool leftKS = leftSlowKey->keyDown(buffer, keyState);
00279 bool leftKVS = leftVSlowKey->keyDown(buffer, keyState);
00280
00281 if (rightK || rightKF || rightKS || rightKVS)
00282 {
00283 float mult = frameTime;
00284 if (rightKF) mult *= 4.0f;
00285 else if (rightKS) mult *= 0.25f;
00286 else if (rightKVS) mult *= 0.05f;
00287
00288 tank->getPosition().rotateGunXY(fixed::fromFloat(-45.0f * mult));
00289 currentLRMoving = true;
00290
00291 leftRightHUD(tank);
00292 }
00293 else if (leftK || leftKF || leftKS || leftKVS)
00294 {
00295 float mult = frameTime;
00296 if (leftKF) mult *= 4.0f;
00297 else if (leftKS) mult *= 0.25f;
00298 else if (leftKVS) mult *= 0.05f;
00299
00300 tank->getPosition().rotateGunXY(fixed::fromFloat(45.0f * mult));
00301 currentLRMoving = true;
00302
00303 leftRightHUD(tank);
00304 }
00305
00306 if (LRMoving != currentLRMoving)
00307 {
00308 CACHE_SOUND(sound, S3D::getDataFile("data/wav/movement/movement.wav"));
00309 CACHE_SOUND(turn, S3D::getDataFile("data/wav/movement/turn.wav"));
00310 if (currentLRMoving)
00311 {
00312 startSound_->play(sound);
00313 rotateSound_->play(turn);
00314 }
00315 else
00316 {
00317 rotateSound_->stop();
00318 }
00319
00320 LRMoving = currentLRMoving;
00321 }
00322 }
00323
00324 void TankKeyboardControlUtil::leftRightHUD(Tank *tank)
00325 {
00326 float rot = tank->getPosition().getRotationGunXY().asFloat() / 360.0f;
00327 TargetRendererImplTankHUD::setText("Rot:",
00328 tank->getPosition().getRotationString(), rot * 100.0f);
00329 }
00330
00331 void TankKeyboardControlUtil::moveUpDown(Tank *tank,
00332 char *buffer, unsigned int keyState, float frameTime)
00333 {
00334 static bool UDMoving = false;
00335 bool currentUDMoving = false;
00336
00337 KEYBOARDKEY("ROTATE_UP", staticUpKey);
00338 KEYBOARDKEY("ROTATE_UP_SLOW", staticUpSlowKey);
00339 KEYBOARDKEY("ROTATE_UP_VSLOW", staticUpVSlowKey);
00340 KEYBOARDKEY("ROTATE_UP_FAST", staticUpFastKey);
00341 KEYBOARDKEY("ROTATE_DOWN", staticDownKey);
00342 KEYBOARDKEY("ROTATE_DOWN_SLOW", staticDownSlowKey);
00343 KEYBOARDKEY("ROTATE_DOWN_VSLOW", staticDownVSlowKey);
00344 KEYBOARDKEY("ROTATE_DOWN_FAST", staticDownFastKey);
00345
00346 KeyboardKey *upKey = staticUpKey;
00347 KeyboardKey *upSlowKey = staticUpSlowKey;
00348 KeyboardKey *upVSlowKey = staticUpVSlowKey;
00349 KeyboardKey *upFastKey = staticUpFastKey;
00350 KeyboardKey *downKey = staticDownKey;
00351 KeyboardKey *downSlowKey = staticDownSlowKey;
00352 KeyboardKey *downVSlowKey = staticDownVSlowKey;
00353 KeyboardKey *downFastKey = staticDownFastKey;
00354 if (OptionsDisplay::instance()->getInvertElevation())
00355 {
00356 upKey = staticDownKey;
00357 upSlowKey = staticDownSlowKey;
00358 upVSlowKey = staticDownVSlowKey;
00359 upFastKey = staticDownFastKey;
00360 downKey = staticUpKey;
00361 downSlowKey = staticUpSlowKey;
00362 downVSlowKey = staticUpVSlowKey;
00363 downFastKey = staticUpFastKey;
00364 }
00365
00366 bool upK = upKey->keyDown(buffer, keyState);
00367 bool upKS = upSlowKey->keyDown(buffer, keyState);
00368 bool upKVS = upVSlowKey->keyDown(buffer, keyState);
00369 bool upKF = upFastKey->keyDown(buffer, keyState);
00370 bool downK = downKey->keyDown(buffer, keyState);
00371 bool downKS = downSlowKey->keyDown(buffer, keyState);
00372 bool downKVS = downVSlowKey->keyDown(buffer, keyState);
00373 bool downKF = downFastKey->keyDown(buffer, keyState);
00374
00375 if (upK || upKS || upKF || upKVS)
00376 {
00377 float mult = frameTime;
00378 if (upKF) mult *= 4.0f;
00379 else if (upKS) mult *= 0.25f;
00380 else if (upKVS) mult *= 0.05f;
00381
00382 tank->getPosition().rotateGunYZ(fixed::fromFloat(-45.0f * mult));
00383 currentUDMoving = true;
00384
00385 upDownHUD(tank);
00386 }
00387 else if (downK || downKS || downKF || downKVS)
00388 {
00389 float mult = frameTime;
00390 if (downKF) mult *= 4.0f;
00391 else if (downKS) mult *= 0.25f;
00392 else if (downKVS) mult *= 0.05f;
00393
00394 tank->getPosition().rotateGunYZ(fixed::fromFloat(45.0f * mult));
00395 currentUDMoving = true;
00396
00397 upDownHUD(tank);
00398 }
00399
00400 if (UDMoving != currentUDMoving)
00401 {
00402 CACHE_SOUND(sound, S3D::getDataFile("data/wav/movement/movement.wav"));
00403 CACHE_SOUND(elevate, S3D::getDataFile("data/wav/movement/elevate.wav"));
00404 if (currentUDMoving)
00405 {
00406 startSound_->play(sound);
00407 elevateSound_->play(elevate);
00408 }
00409 else
00410 {
00411 elevateSound_->stop();
00412 }
00413
00414 UDMoving = currentUDMoving;
00415 }
00416 }
00417
00418 void TankKeyboardControlUtil::upDownHUD(Tank *tank)
00419 {
00420 float rot = tank->getPosition().getRotationGunYZ().asFloat() / 90.0f;
00421 TargetRendererImplTankHUD::setText("Ele:",
00422 tank->getPosition().getElevationString(), rot * 100.0f);
00423 }
00424
00425 void TankKeyboardControlUtil::movePower(Tank *tank,
00426 char *buffer, unsigned int keyState, float frameTime)
00427 {
00428 static bool PMoving = false;
00429 bool currentPMoving = false;
00430
00431 KEYBOARDKEY("INCREASE_POWER", incKey);
00432 KEYBOARDKEY("INCREASE_POWER_SLOW", incSlowKey);
00433 KEYBOARDKEY("INCREASE_POWER_VSLOW", incVSlowKey);
00434 KEYBOARDKEY("INCREASE_POWER_FAST", incFastKey);
00435 KEYBOARDKEY("DECREASE_POWER", decKey);
00436 KEYBOARDKEY("DECREASE_POWER_SLOW", decSlowKey);
00437 KEYBOARDKEY("DECREASE_POWER_VSLOW", decVSlowKey);
00438 KEYBOARDKEY("DECREASE_POWER_FAST", decFastKey);
00439 bool incK = incKey->keyDown(buffer, keyState);
00440 bool incKS = incSlowKey->keyDown(buffer, keyState);
00441 bool incKVS = incVSlowKey->keyDown(buffer, keyState);
00442 bool incKF = incFastKey->keyDown(buffer, keyState);
00443 bool decK = decKey->keyDown(buffer, keyState);
00444 bool decKS = decSlowKey->keyDown(buffer, keyState);
00445 bool decKVS = decVSlowKey->keyDown(buffer, keyState);
00446 bool decKF = decFastKey->keyDown(buffer, keyState);
00447
00448 if (incK || incKS || incKF || incKVS)
00449 {
00450 float mult = frameTime;
00451 if (incKF) mult *= 4.0f;
00452 else if (incKS) mult *= 0.25f;
00453 else if (incKVS) mult *= 0.05f;
00454
00455 tank->getPosition().changePower(fixed::fromFloat(250.0f * mult));
00456 currentPMoving = true;
00457
00458 powerHUD(tank);
00459 }
00460 else if (decK || decKS || decKF || decKVS)
00461 {
00462 float mult = frameTime;
00463 if (decKF) mult *= 4.0f;
00464 else if (decKS) mult *= 0.25f;
00465 else if (decKVS) mult *= 0.05f;
00466
00467 tank->getPosition().changePower(fixed::fromFloat(-250.0f * mult));
00468 currentPMoving = true;
00469
00470 powerHUD(tank);
00471 }
00472
00473 if (PMoving != currentPMoving)
00474 {
00475 CACHE_SOUND(power, S3D::getDataFile("data/wav/movement/power.wav"));
00476 if (currentPMoving)
00477 {
00478 powerSound_->play(power);
00479 }
00480 else
00481 {
00482 powerSound_->stop();
00483 }
00484
00485 PMoving = currentPMoving;
00486 }
00487 }
00488
00489 void TankKeyboardControlUtil::powerHUD(Tank *tank)
00490 {
00491 float power = tank->getPosition().getPower().asFloat() /
00492 tank->getPosition().getMaxPower().asFloat();
00493 TargetRendererImplTankHUD::setText("Pwr:",
00494 tank->getPosition().getPowerString(), power * 100.0f);
00495 }
00496
00497
00498 void TankKeyboardControlUtil::fireShot(Tank *tank)
00499 {
00500 Accessory *currentWeapon =
00501 tank->getAccessories().getWeapons().getCurrent();
00502 if (currentWeapon)
00503 {
00504
00505 ComsPlayedMoveMessage comsMessage(tank->getPlayerId(), ComsPlayedMoveMessage::eShot);
00506 comsMessage.setShot(
00507 currentWeapon->getAccessoryId(),
00508 tank->getPosition().getRotationGunXY(),
00509 tank->getPosition().getRotationGunYZ(),
00510 tank->getPosition().getPower(),
00511 tank->getPosition().getSelectPositionX(),
00512 tank->getPosition().getSelectPositionY());
00513
00514
00515 ComsMessageSender::sendToServer(comsMessage);
00516
00517
00518 ScorchedClient::instance()->getGameState().stimulate(ClientState::StimWait);
00519 }
00520 }
00521
00522 void TankKeyboardControlUtil::skipShot(Tank *tank)
00523 {
00524
00525 ComsPlayedMoveMessage comsMessage(tank->getPlayerId(), ComsPlayedMoveMessage::eSkip);
00526
00527
00528
00529 ComsMessageSender::sendToServer(comsMessage);
00530
00531
00532 ScorchedClient::instance()->getGameState().stimulate(ClientState::StimWait);
00533 }
00534
00535 void TankKeyboardControlUtil::resign(Tank *tank)
00536 {
00537
00538 ComsPlayedMoveMessage comsMessage(tank->getPlayerId(), ComsPlayedMoveMessage::eResign);
00539
00540
00541
00542 ComsMessageSender::sendToServer(comsMessage);
00543
00544
00545 ScorchedClient::instance()->getGameState().stimulate(ClientState::StimWait);
00546 }
00547
00548 void TankKeyboardControlUtil::parachutesUpDown(Tank *tank, unsigned int paraId)
00549 {
00550 ComsDefenseMessage defenseMessage(
00551 tank->getPlayerId(),
00552 (paraId!=0)?ComsDefenseMessage::eParachutesUp:ComsDefenseMessage::eParachutesDown,
00553 paraId);
00554 ComsMessageSender::sendToServer(defenseMessage);
00555 }
00556
00557 void TankKeyboardControlUtil::shieldsUpDown(Tank *tank, unsigned int shieldId)
00558 {
00559 ComsDefenseMessage defenseMessage(
00560 tank->getPlayerId(),
00561 (shieldId!=0)?ComsDefenseMessage::eShieldUp:ComsDefenseMessage::eShieldDown,
00562 shieldId);
00563 ComsMessageSender::sendToServer(defenseMessage);
00564 }
00565
00566 void TankKeyboardControlUtil::useBattery(Tank *tank, unsigned int batteryId)
00567 {
00568 ComsDefenseMessage defenseMessage(
00569 tank->getPlayerId(),
00570 ComsDefenseMessage::eBatteryUse,
00571 batteryId);
00572 ComsMessageSender::sendToServer(defenseMessage);
00573 }