GameBearShootWindow.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "../framework/Session_local.h"
  23. #include "DeviceContext.h"
  24. #include "Window.h"
  25. #include "UserInterfaceLocal.h"
  26. #include "GameBearShootWindow.h"
  27. #define BEAR_GRAVITY 240
  28. #define BEAR_SIZE 24.f
  29. #define BEAR_SHRINK_TIME 2000.f
  30. #define MAX_WINDFORCE 100.f
  31. idCVar bearTurretAngle( "bearTurretAngle", "0", CVAR_FLOAT, "" );
  32. idCVar bearTurretForce( "bearTurretForce", "200", CVAR_FLOAT, "" );
  33. /*
  34. *****************************************************************************
  35. * BSEntity
  36. ****************************************************************************
  37. */
  38. BSEntity::BSEntity(idGameBearShootWindow* _game) {
  39. game = _game;
  40. visible = true;
  41. entColor = colorWhite;
  42. materialName = "";
  43. material = NULL;
  44. width = height = 8;
  45. rotation = 0.f;
  46. rotationSpeed = 0.f;
  47. fadeIn = false;
  48. fadeOut = false;
  49. position.Zero();
  50. velocity.Zero();
  51. }
  52. BSEntity::~BSEntity() {
  53. }
  54. /*
  55. ======================
  56. BSEntity::WriteToSaveGame
  57. ======================
  58. */
  59. void BSEntity::WriteToSaveGame( idFile *savefile ) {
  60. game->WriteSaveGameString( materialName, savefile );
  61. savefile->Write( &width, sizeof(width) );
  62. savefile->Write( &height, sizeof(height) );
  63. savefile->Write( &visible, sizeof(visible) );
  64. savefile->Write( &entColor, sizeof(entColor) );
  65. savefile->Write( &position, sizeof(position) );
  66. savefile->Write( &rotation, sizeof(rotation) );
  67. savefile->Write( &rotationSpeed, sizeof(rotationSpeed) );
  68. savefile->Write( &velocity, sizeof(velocity) );
  69. savefile->Write( &fadeIn, sizeof(fadeIn) );
  70. savefile->Write( &fadeOut, sizeof(fadeOut) );
  71. }
  72. /*
  73. ======================
  74. BSEntity::ReadFromSaveGame
  75. ======================
  76. */
  77. void BSEntity::ReadFromSaveGame( idFile *savefile, idGameBearShootWindow* _game ) {
  78. game = _game;
  79. game->ReadSaveGameString( materialName, savefile );
  80. SetMaterial( materialName );
  81. savefile->Read( &width, sizeof(width) );
  82. savefile->Read( &height, sizeof(height) );
  83. savefile->Read( &visible, sizeof(visible) );
  84. savefile->Read( &entColor, sizeof(entColor) );
  85. savefile->Read( &position, sizeof(position) );
  86. savefile->Read( &rotation, sizeof(rotation) );
  87. savefile->Read( &rotationSpeed, sizeof(rotationSpeed) );
  88. savefile->Read( &velocity, sizeof(velocity) );
  89. savefile->Read( &fadeIn, sizeof(fadeIn) );
  90. savefile->Read( &fadeOut, sizeof(fadeOut) );
  91. }
  92. /*
  93. ======================
  94. BSEntity::SetMaterial
  95. ======================
  96. */
  97. void BSEntity::SetMaterial(const char* name) {
  98. materialName = name;
  99. material = declManager->FindMaterial( name );
  100. material->SetSort( SS_GUI );
  101. }
  102. /*
  103. ======================
  104. BSEntity::SetSize
  105. ======================
  106. */
  107. void BSEntity::SetSize( float _width, float _height ) {
  108. width = _width;
  109. height = _height;
  110. }
  111. /*
  112. ======================
  113. BSEntity::SetVisible
  114. ======================
  115. */
  116. void BSEntity::SetVisible( bool isVisible ) {
  117. visible = isVisible;
  118. }
  119. /*
  120. ======================
  121. BSEntity::Update
  122. ======================
  123. */
  124. void BSEntity::Update( float timeslice ) {
  125. if ( !visible ) {
  126. return;
  127. }
  128. // Fades
  129. if ( fadeIn && entColor.w < 1.f ) {
  130. entColor.w += 1 * timeslice;
  131. if ( entColor.w >= 1.f ) {
  132. entColor.w = 1.f;
  133. fadeIn = false;
  134. }
  135. }
  136. if ( fadeOut && entColor.w > 0.f ) {
  137. entColor.w -= 1 * timeslice;
  138. if ( entColor.w <= 0.f ) {
  139. entColor.w = 0.f;
  140. fadeOut = false;
  141. }
  142. }
  143. // Move the entity
  144. position += velocity * timeslice;
  145. // Rotate Entity
  146. rotation += rotationSpeed * timeslice;
  147. }
  148. /*
  149. ======================
  150. BSEntity::Draw
  151. ======================
  152. */
  153. void BSEntity::Draw(idDeviceContext *dc) {
  154. if ( visible ) {
  155. dc->DrawMaterialRotated( position.x, position.y, width, height, material, entColor, 1.0f, 1.0f, DEG2RAD(rotation) );
  156. }
  157. }
  158. /*
  159. *****************************************************************************
  160. * idGameBearShootWindow
  161. ****************************************************************************
  162. */
  163. idGameBearShootWindow::idGameBearShootWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) {
  164. dc = d;
  165. gui = g;
  166. CommonInit();
  167. }
  168. idGameBearShootWindow::idGameBearShootWindow(idUserInterfaceLocal *g) : idWindow(g) {
  169. gui = g;
  170. CommonInit();
  171. }
  172. idGameBearShootWindow::~idGameBearShootWindow() {
  173. entities.DeleteContents(true);
  174. }
  175. /*
  176. =============================
  177. idGameBearShootWindow::WriteToSaveGame
  178. =============================
  179. */
  180. void idGameBearShootWindow::WriteToSaveGame( idFile *savefile ) {
  181. idWindow::WriteToSaveGame( savefile );
  182. gamerunning.WriteToSaveGame( savefile );
  183. onFire.WriteToSaveGame( savefile );
  184. onContinue.WriteToSaveGame( savefile );
  185. onNewGame.WriteToSaveGame( savefile );
  186. savefile->Write( &timeSlice, sizeof(timeSlice) );
  187. savefile->Write( &timeRemaining, sizeof(timeRemaining) );
  188. savefile->Write( &gameOver, sizeof(gameOver) );
  189. savefile->Write( &currentLevel, sizeof(currentLevel) );
  190. savefile->Write( &goalsHit, sizeof(goalsHit) );
  191. savefile->Write( &updateScore, sizeof(updateScore) );
  192. savefile->Write( &bearHitTarget, sizeof(bearHitTarget) );
  193. savefile->Write( &bearScale, sizeof(bearScale) );
  194. savefile->Write( &bearIsShrinking, sizeof(bearIsShrinking) );
  195. savefile->Write( &bearShrinkStartTime, sizeof(bearShrinkStartTime) );
  196. savefile->Write( &turretAngle, sizeof(turretAngle) );
  197. savefile->Write( &turretForce, sizeof(turretForce) );
  198. savefile->Write( &windForce, sizeof(windForce) );
  199. savefile->Write( &windUpdateTime, sizeof(windUpdateTime) );
  200. int numberOfEnts = entities.Num();
  201. savefile->Write( &numberOfEnts, sizeof(numberOfEnts) );
  202. for ( int i=0; i<numberOfEnts; i++ ) {
  203. entities[i]->WriteToSaveGame( savefile );
  204. }
  205. int index;
  206. index = entities.FindIndex( turret );
  207. savefile->Write( &index, sizeof(index) );
  208. index = entities.FindIndex( bear );
  209. savefile->Write( &index, sizeof(index) );
  210. index = entities.FindIndex( helicopter );
  211. savefile->Write( &index, sizeof(index) );
  212. index = entities.FindIndex( goal );
  213. savefile->Write( &index, sizeof(index) );
  214. index = entities.FindIndex( wind );
  215. savefile->Write( &index, sizeof(index) );
  216. index = entities.FindIndex( gunblast );
  217. savefile->Write( &index, sizeof(index) );
  218. }
  219. /*
  220. =============================
  221. idGameBearShootWindow::ReadFromSaveGame
  222. =============================
  223. */
  224. void idGameBearShootWindow::ReadFromSaveGame( idFile *savefile ) {
  225. idWindow::ReadFromSaveGame( savefile );
  226. // Remove all existing entities
  227. entities.DeleteContents(true);
  228. gamerunning.ReadFromSaveGame( savefile );
  229. onFire.ReadFromSaveGame( savefile );
  230. onContinue.ReadFromSaveGame( savefile );
  231. onNewGame.ReadFromSaveGame( savefile );
  232. savefile->Read( &timeSlice, sizeof(timeSlice) );
  233. savefile->Read( &timeRemaining, sizeof(timeRemaining) );
  234. savefile->Read( &gameOver, sizeof(gameOver) );
  235. savefile->Read( &currentLevel, sizeof(currentLevel) );
  236. savefile->Read( &goalsHit, sizeof(goalsHit) );
  237. savefile->Read( &updateScore, sizeof(updateScore) );
  238. savefile->Read( &bearHitTarget, sizeof(bearHitTarget) );
  239. savefile->Read( &bearScale, sizeof(bearScale) );
  240. savefile->Read( &bearIsShrinking, sizeof(bearIsShrinking) );
  241. savefile->Read( &bearShrinkStartTime, sizeof(bearShrinkStartTime) );
  242. savefile->Read( &turretAngle, sizeof(turretAngle) );
  243. savefile->Read( &turretForce, sizeof(turretForce) );
  244. savefile->Read( &windForce, sizeof(windForce) );
  245. savefile->Read( &windUpdateTime, sizeof(windUpdateTime) );
  246. int numberOfEnts;
  247. savefile->Read( &numberOfEnts, sizeof(numberOfEnts) );
  248. for ( int i=0; i<numberOfEnts; i++ ) {
  249. BSEntity *ent;
  250. ent = new BSEntity( this );
  251. ent->ReadFromSaveGame( savefile, this );
  252. entities.Append( ent );
  253. }
  254. int index;
  255. savefile->Read( &index, sizeof(index) );
  256. turret = entities[index];
  257. savefile->Read( &index, sizeof(index) );
  258. bear = entities[index];
  259. savefile->Read( &index, sizeof(index) );
  260. helicopter = entities[index];
  261. savefile->Read( &index, sizeof(index) );
  262. goal = entities[index];
  263. savefile->Read( &index, sizeof(index) );
  264. wind = entities[index];
  265. savefile->Read( &index, sizeof(index) );
  266. gunblast = entities[index];
  267. }
  268. /*
  269. =============================
  270. idGameBearShootWindow::ResetGameState
  271. =============================
  272. */
  273. void idGameBearShootWindow::ResetGameState() {
  274. gamerunning = false;
  275. gameOver = false;
  276. onFire = false;
  277. onContinue = false;
  278. onNewGame = false;
  279. // Game moves forward 16 milliseconds every frame
  280. timeSlice = 0.016f;
  281. timeRemaining = 60.f;
  282. goalsHit = 0;
  283. updateScore = false;
  284. bearHitTarget = false;
  285. currentLevel = 1;
  286. turretAngle = 0.f;
  287. turretForce = 200.f;
  288. windForce = 0.f;
  289. windUpdateTime = 0;
  290. bearIsShrinking = false;
  291. bearShrinkStartTime = 0;
  292. bearScale = 1.f;
  293. }
  294. /*
  295. =============================
  296. idGameBearShootWindow::CommonInit
  297. =============================
  298. */
  299. void idGameBearShootWindow::CommonInit() {
  300. BSEntity * ent;
  301. // Precache sounds
  302. declManager->FindSound( "arcade_beargroan" );
  303. declManager->FindSound( "arcade_sargeshoot" );
  304. declManager->FindSound( "arcade_balloonpop" );
  305. declManager->FindSound( "arcade_levelcomplete1" );
  306. // Precache dynamically used materials
  307. declManager->FindMaterial( "game/bearshoot/helicopter_broken" );
  308. declManager->FindMaterial( "game/bearshoot/goal_dead" );
  309. declManager->FindMaterial( "game/bearshoot/gun_blast" );
  310. ResetGameState();
  311. ent = new BSEntity( this );
  312. turret = ent;
  313. ent->SetMaterial( "game/bearshoot/turret" );
  314. ent->SetSize( 272, 144 );
  315. ent->position.x = -44;
  316. ent->position.y = 260;
  317. entities.Append( ent );
  318. ent = new BSEntity( this );
  319. ent->SetMaterial( "game/bearshoot/turret_base" );
  320. ent->SetSize( 144, 160 );
  321. ent->position.x = 16;
  322. ent->position.y = 280;
  323. entities.Append( ent );
  324. ent = new BSEntity( this );
  325. bear = ent;
  326. ent->SetMaterial( "game/bearshoot/bear" );
  327. ent->SetSize( BEAR_SIZE, BEAR_SIZE );
  328. ent->SetVisible( false );
  329. ent->position.x = 0;
  330. ent->position.y = 0;
  331. entities.Append( ent );
  332. ent = new BSEntity( this );
  333. helicopter = ent;
  334. ent->SetMaterial( "game/bearshoot/helicopter" );
  335. ent->SetSize( 64, 64 );
  336. ent->position.x = 550;
  337. ent->position.y = 100;
  338. entities.Append( ent );
  339. ent = new BSEntity( this );
  340. goal = ent;
  341. ent->SetMaterial( "game/bearshoot/goal" );
  342. ent->SetSize( 64, 64 );
  343. ent->position.x = 550;
  344. ent->position.y = 164;
  345. entities.Append( ent );
  346. ent = new BSEntity( this );
  347. wind = ent;
  348. ent->SetMaterial( "game/bearshoot/wind" );
  349. ent->SetSize( 100, 40 );
  350. ent->position.x = 500;
  351. ent->position.y = 430;
  352. entities.Append( ent );
  353. ent = new BSEntity( this );
  354. gunblast = ent;
  355. ent->SetMaterial( "game/bearshoot/gun_blast" );
  356. ent->SetSize( 64, 64 );
  357. ent->SetVisible( false );
  358. entities.Append( ent );
  359. }
  360. /*
  361. =============================
  362. idGameBearShootWindow::HandleEvent
  363. =============================
  364. */
  365. const char *idGameBearShootWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) {
  366. int key = event->evValue;
  367. // need to call this to allow proper focus and capturing on embedded children
  368. const char *ret = idWindow::HandleEvent(event, updateVisuals);
  369. if ( event->evType == SE_KEY ) {
  370. if ( !event->evValue2 ) {
  371. return ret;
  372. }
  373. if ( key == K_MOUSE1) {
  374. // Mouse was clicked
  375. } else {
  376. return ret;
  377. }
  378. }
  379. return ret;
  380. }
  381. /*
  382. =============================
  383. idGameBearShootWindow::ParseInternalVar
  384. =============================
  385. */
  386. bool idGameBearShootWindow::ParseInternalVar(const char *_name, idParser *src) {
  387. if ( idStr::Icmp(_name, "gamerunning") == 0 ) {
  388. gamerunning = src->ParseBool();
  389. return true;
  390. }
  391. if ( idStr::Icmp(_name, "onFire") == 0 ) {
  392. onFire = src->ParseBool();
  393. return true;
  394. }
  395. if ( idStr::Icmp(_name, "onContinue") == 0 ) {
  396. onContinue = src->ParseBool();
  397. return true;
  398. }
  399. if ( idStr::Icmp(_name, "onNewGame") == 0 ) {
  400. onNewGame = src->ParseBool();
  401. return true;
  402. }
  403. return idWindow::ParseInternalVar(_name, src);
  404. }
  405. /*
  406. =============================
  407. idGameBearShootWindow::GetWinVarByName
  408. =============================
  409. */
  410. idWinVar *idGameBearShootWindow::GetWinVarByName(const char *_name, bool winLookup, drawWin_t** owner) {
  411. idWinVar *retVar = NULL;
  412. if ( idStr::Icmp(_name, "gamerunning") == 0 ) {
  413. retVar = &gamerunning;
  414. } else if ( idStr::Icmp(_name, "onFire") == 0 ) {
  415. retVar = &onFire;
  416. } else if ( idStr::Icmp(_name, "onContinue") == 0 ) {
  417. retVar = &onContinue;
  418. } else if ( idStr::Icmp(_name, "onNewGame") == 0 ) {
  419. retVar = &onNewGame;
  420. }
  421. if(retVar) {
  422. return retVar;
  423. }
  424. return idWindow::GetWinVarByName(_name, winLookup, owner);
  425. }
  426. /*
  427. =============================
  428. idGameBearShootWindow::PostParse
  429. =============================
  430. */
  431. void idGameBearShootWindow::PostParse() {
  432. idWindow::PostParse();
  433. }
  434. /*
  435. =============================
  436. idGameBearShootWindow::Draw
  437. =============================
  438. */
  439. void idGameBearShootWindow::Draw(int time, float x, float y) {
  440. int i;
  441. //Update the game every frame before drawing
  442. UpdateGame();
  443. for( i = entities.Num()-1; i >= 0; i-- ) {
  444. entities[i]->Draw(dc);
  445. }
  446. }
  447. /*
  448. =============================
  449. idGameBearShootWindow::Activate
  450. =============================
  451. */
  452. const char *idGameBearShootWindow::Activate(bool activate) {
  453. return "";
  454. }
  455. /*
  456. =============================
  457. idGameBearShootWindow::UpdateTurret
  458. =============================
  459. */
  460. void idGameBearShootWindow::UpdateTurret() {
  461. idVec2 pt;
  462. idVec2 turretOrig;
  463. idVec2 right;
  464. float dot, angle;
  465. pt.x = gui->CursorX();
  466. pt.y = gui->CursorY();
  467. turretOrig.Set( 80.f, 348.f );
  468. pt = pt - turretOrig;
  469. pt.NormalizeFast();
  470. right.x = 1.f;
  471. right.y = 0.f;
  472. dot = pt * right;
  473. angle = RAD2DEG( acosf( dot ) );
  474. turretAngle = idMath::ClampFloat( 0.f, 90.f, angle );
  475. }
  476. /*
  477. =============================
  478. idGameBearShootWindow::UpdateBear
  479. =============================
  480. */
  481. void idGameBearShootWindow::UpdateBear() {
  482. int time = gui->GetTime();
  483. bool startShrink = false;
  484. // Apply gravity
  485. bear->velocity.y += BEAR_GRAVITY * timeSlice;
  486. // Apply wind
  487. bear->velocity.x += windForce * timeSlice;
  488. // Check for collisions
  489. if ( !bearHitTarget && !gameOver ) {
  490. idVec2 bearCenter;
  491. bool collision = false;
  492. bearCenter.x = bear->position.x + bear->width/2;
  493. bearCenter.y = bear->position.y + bear->height/2;
  494. if ( bearCenter.x > (helicopter->position.x + 16) && bearCenter.x < (helicopter->position.x + helicopter->width - 29) ) {
  495. if ( bearCenter.y > (helicopter->position.y + 12) && bearCenter.y < (helicopter->position.y + helicopter->height - 7) ) {
  496. collision = true;
  497. }
  498. }
  499. if ( collision ) {
  500. // balloons pop and bear tumbles to ground
  501. helicopter->SetMaterial( "game/bearshoot/helicopter_broken" );
  502. helicopter->velocity.y = 230.f;
  503. goal->velocity.y = 230.f;
  504. session->sw->PlayShaderDirectly( "arcade_balloonpop" );
  505. bear->SetVisible( false );
  506. if ( bear->velocity.x > 0 ) {
  507. bear->velocity.x *= -1.f;
  508. }
  509. bear->velocity *= 0.666f;
  510. bearHitTarget = true;
  511. updateScore = true;
  512. startShrink = true;
  513. }
  514. }
  515. // Check for ground collision
  516. if ( bear->position.y > 380 ) {
  517. bear->position.y = 380;
  518. if ( bear->velocity.Length() < 25 ) {
  519. bear->velocity.Zero();
  520. } else {
  521. startShrink = true;
  522. bear->velocity.y *= -1.f;
  523. bear->velocity *= 0.5f;
  524. if ( bearScale ) {
  525. session->sw->PlayShaderDirectly( "arcade_balloonpop" );
  526. }
  527. }
  528. }
  529. // Bear rotation is based on velocity
  530. float angle;
  531. idVec2 dir;
  532. dir = bear->velocity;
  533. dir.NormalizeFast();
  534. angle = RAD2DEG( atan2( dir.x, dir.y ) );
  535. bear->rotation = angle - 90;
  536. // Update Bear scale
  537. if ( bear->position.x > 650 ) {
  538. startShrink = true;
  539. }
  540. if ( !bearIsShrinking && bearScale && startShrink ) {
  541. bearShrinkStartTime = time;
  542. bearIsShrinking = true;
  543. }
  544. if ( bearIsShrinking ) {
  545. if ( bearHitTarget ) {
  546. bearScale = 1 - ( (float)(time - bearShrinkStartTime) / BEAR_SHRINK_TIME );
  547. } else {
  548. bearScale = 1 - ( (float)(time - bearShrinkStartTime) / 750 );
  549. }
  550. bearScale *= BEAR_SIZE;
  551. bear->SetSize( bearScale, bearScale );
  552. if ( bearScale < 0 ) {
  553. gui->HandleNamedEvent( "EnableFireButton" );
  554. bearIsShrinking = false;
  555. bearScale = 0.f;
  556. if ( bearHitTarget ) {
  557. goal->SetMaterial( "game/bearshoot/goal" );
  558. goal->position.x = 550;
  559. goal->position.y = 164;
  560. goal->velocity.Zero();
  561. goal->velocity.y = (currentLevel-1) * 30;
  562. goal->entColor.w = 0.f;
  563. goal->fadeIn = true;
  564. goal->fadeOut = false;
  565. helicopter->SetVisible( true );
  566. helicopter->SetMaterial( "game/bearshoot/helicopter" );
  567. helicopter->position.x = 550;
  568. helicopter->position.y = 100;
  569. helicopter->velocity.Zero();
  570. helicopter->velocity.y = goal->velocity.y;
  571. helicopter->entColor.w = 0.f;
  572. helicopter->fadeIn = true;
  573. helicopter->fadeOut = false;
  574. }
  575. }
  576. }
  577. }
  578. /*
  579. =============================
  580. idGameBearShootWindow::UpdateHelicopter
  581. =============================
  582. */
  583. void idGameBearShootWindow::UpdateHelicopter() {
  584. if ( bearHitTarget && bearIsShrinking ) {
  585. if ( helicopter->velocity.y != 0 && helicopter->position.y > 264 ) {
  586. helicopter->velocity.y = 0;
  587. goal->velocity.y = 0;
  588. helicopter->SetVisible( false );
  589. goal->SetMaterial( "game/bearshoot/goal_dead" );
  590. session->sw->PlayShaderDirectly( "arcade_beargroan", 1 );
  591. helicopter->fadeOut = true;
  592. goal->fadeOut = true;
  593. }
  594. } else if ( currentLevel > 1 ) {
  595. int height = helicopter->position.y;
  596. float speed = (currentLevel-1) * 30;
  597. if ( height > 240 ) {
  598. helicopter->velocity.y = -speed;
  599. goal->velocity.y = -speed;
  600. } else if ( height < 30 ) {
  601. helicopter->velocity.y = speed;
  602. goal->velocity.y = speed;
  603. }
  604. }
  605. }
  606. /*
  607. =============================
  608. idGameBearShootWindow::UpdateButtons
  609. =============================
  610. */
  611. void idGameBearShootWindow::UpdateButtons() {
  612. if ( onFire ) {
  613. idVec2 vec;
  614. gui->HandleNamedEvent( "DisableFireButton" );
  615. session->sw->PlayShaderDirectly( "arcade_sargeshoot" );
  616. bear->SetVisible( true );
  617. bearScale = 1.f;
  618. bear->SetSize( BEAR_SIZE, BEAR_SIZE );
  619. vec.x = idMath::Cos( DEG2RAD(turretAngle) );
  620. vec.x += ( 1 - vec.x ) * 0.18f;
  621. vec.y = -idMath::Sin( DEG2RAD(turretAngle) );
  622. turretForce = bearTurretForce.GetFloat();
  623. bear->position.x = 80 + ( 96 * vec.x );
  624. bear->position.y = 334 + ( 96 * vec.y );
  625. bear->velocity.x = vec.x * turretForce;
  626. bear->velocity.y = vec.y * turretForce;
  627. gunblast->position.x = 55 + ( 96 * vec.x );
  628. gunblast->position.y = 310 + ( 100 * vec.y );
  629. gunblast->SetVisible( true );
  630. gunblast->entColor.w = 1.f;
  631. gunblast->rotation = turretAngle;
  632. gunblast->fadeOut = true;
  633. bearHitTarget = false;
  634. onFire = false;
  635. }
  636. }
  637. /*
  638. =============================
  639. idGameBearShootWindow::UpdateScore
  640. =============================
  641. */
  642. void idGameBearShootWindow::UpdateScore() {
  643. if ( gameOver ) {
  644. gui->HandleNamedEvent( "GameOver" );
  645. return;
  646. }
  647. goalsHit++;
  648. gui->SetStateString( "player_score", va("%i", goalsHit ) );
  649. // Check for level progression
  650. if ( !(goalsHit % 5) ) {
  651. currentLevel++;
  652. gui->SetStateString( "current_level", va("%i", currentLevel ) );
  653. session->sw->PlayShaderDirectly( "arcade_levelcomplete1", 3 );
  654. timeRemaining += 30;
  655. }
  656. }
  657. /*
  658. =============================
  659. idGameBearShootWindow::UpdateGame
  660. =============================
  661. */
  662. void idGameBearShootWindow::UpdateGame() {
  663. int i;
  664. if ( onNewGame ) {
  665. ResetGameState();
  666. goal->position.x = 550;
  667. goal->position.y = 164;
  668. goal->velocity.Zero();
  669. helicopter->position.x = 550;
  670. helicopter->position.y = 100;
  671. helicopter->velocity.Zero();
  672. bear->SetVisible( false );
  673. bearTurretAngle.SetFloat( 0.f );
  674. bearTurretForce.SetFloat( 200.f );
  675. gamerunning = true;
  676. }
  677. if ( onContinue ) {
  678. gameOver = false;
  679. timeRemaining = 60.f;
  680. onContinue = false;
  681. }
  682. if(gamerunning == true) {
  683. int current_time = gui->GetTime();
  684. idRandom rnd( current_time );
  685. // Check for button presses
  686. UpdateButtons();
  687. if ( bear ) {
  688. UpdateBear();
  689. }
  690. if ( helicopter && goal ) {
  691. UpdateHelicopter();
  692. }
  693. // Update Wind
  694. if ( windUpdateTime < current_time ) {
  695. float scale;
  696. int width;
  697. windForce = rnd.CRandomFloat() * ( MAX_WINDFORCE * 0.75f );
  698. if (windForce > 0) {
  699. windForce += ( MAX_WINDFORCE * 0.25f );
  700. wind->rotation = 0;
  701. } else {
  702. windForce -= ( MAX_WINDFORCE * 0.25f );
  703. wind->rotation = 180;
  704. }
  705. scale = 1.f - (( MAX_WINDFORCE - idMath::Fabs(windForce) ) / MAX_WINDFORCE);
  706. width = 100*scale;
  707. if ( windForce < 0 ) {
  708. wind->position.x = 500 - width + 1;
  709. } else {
  710. wind->position.x = 500;
  711. }
  712. wind->SetSize( width, 40 );
  713. windUpdateTime = current_time + 7000 + rnd.RandomInt(5000);
  714. }
  715. // Update turret rotation angle
  716. if ( turret ) {
  717. turretAngle = bearTurretAngle.GetFloat();
  718. turret->rotation = turretAngle;
  719. }
  720. for( i = 0; i < entities.Num(); i++ ) {
  721. entities[i]->Update( timeSlice );
  722. }
  723. // Update countdown timer
  724. timeRemaining -= timeSlice;
  725. timeRemaining = idMath::ClampFloat( 0.f, 99999.f, timeRemaining );
  726. gui->SetStateString( "time_remaining", va("%2.1f", timeRemaining ) );
  727. if ( timeRemaining <= 0.f && !gameOver ) {
  728. gameOver = true;
  729. updateScore = true;
  730. }
  731. if ( updateScore ) {
  732. UpdateScore();
  733. updateScore = false;
  734. }
  735. }
  736. }