mirror of
https://github.com/blendogames/quadrilateralcowboy.git
synced 2024-11-24 21:11:49 +00:00
896 lines
22 KiB
C++
896 lines
22 KiB
C++
|
/*
|
||
|
===========================================================================
|
||
|
|
||
|
Doom 3 GPL Source Code
|
||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||
|
|
||
|
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||
|
|
||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
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.
|
||
|
|
||
|
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.
|
||
|
|
||
|
===========================================================================
|
||
|
*/
|
||
|
#include "../idlib/precompiled.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include "../framework/Session_local.h"
|
||
|
|
||
|
#include "DeviceContext.h"
|
||
|
#include "Window.h"
|
||
|
#include "UserInterfaceLocal.h"
|
||
|
#include "GameBearShootWindow.h"
|
||
|
|
||
|
|
||
|
#define BEAR_GRAVITY 240
|
||
|
#define BEAR_SIZE 24.f
|
||
|
#define BEAR_SHRINK_TIME 2000.f
|
||
|
|
||
|
#define MAX_WINDFORCE 100.f
|
||
|
|
||
|
idCVar bearTurretAngle( "bearTurretAngle", "0", CVAR_FLOAT, "" );
|
||
|
idCVar bearTurretForce( "bearTurretForce", "200", CVAR_FLOAT, "" );
|
||
|
|
||
|
/*
|
||
|
*****************************************************************************
|
||
|
* BSEntity
|
||
|
****************************************************************************
|
||
|
*/
|
||
|
BSEntity::BSEntity(idGameBearShootWindow* _game) {
|
||
|
game = _game;
|
||
|
visible = true;
|
||
|
|
||
|
entColor = colorWhite;
|
||
|
materialName = "";
|
||
|
material = NULL;
|
||
|
width = height = 8;
|
||
|
rotation = 0.f;
|
||
|
rotationSpeed = 0.f;
|
||
|
fadeIn = false;
|
||
|
fadeOut = false;
|
||
|
|
||
|
position.Zero();
|
||
|
velocity.Zero();
|
||
|
}
|
||
|
|
||
|
BSEntity::~BSEntity() {
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
======================
|
||
|
BSEntity::WriteToSaveGame
|
||
|
======================
|
||
|
*/
|
||
|
void BSEntity::WriteToSaveGame( idFile *savefile ) {
|
||
|
|
||
|
game->WriteSaveGameString( materialName, savefile );
|
||
|
|
||
|
savefile->Write( &width, sizeof(width) );
|
||
|
savefile->Write( &height, sizeof(height) );
|
||
|
savefile->Write( &visible, sizeof(visible) );
|
||
|
|
||
|
savefile->Write( &entColor, sizeof(entColor) );
|
||
|
savefile->Write( &position, sizeof(position) );
|
||
|
savefile->Write( &rotation, sizeof(rotation) );
|
||
|
savefile->Write( &rotationSpeed, sizeof(rotationSpeed) );
|
||
|
savefile->Write( &velocity, sizeof(velocity) );
|
||
|
|
||
|
savefile->Write( &fadeIn, sizeof(fadeIn) );
|
||
|
savefile->Write( &fadeOut, sizeof(fadeOut) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
======================
|
||
|
BSEntity::ReadFromSaveGame
|
||
|
======================
|
||
|
*/
|
||
|
void BSEntity::ReadFromSaveGame( idFile *savefile, idGameBearShootWindow* _game ) {
|
||
|
game = _game;
|
||
|
|
||
|
game->ReadSaveGameString( materialName, savefile );
|
||
|
SetMaterial( materialName );
|
||
|
|
||
|
savefile->Read( &width, sizeof(width) );
|
||
|
savefile->Read( &height, sizeof(height) );
|
||
|
savefile->Read( &visible, sizeof(visible) );
|
||
|
|
||
|
savefile->Read( &entColor, sizeof(entColor) );
|
||
|
savefile->Read( &position, sizeof(position) );
|
||
|
savefile->Read( &rotation, sizeof(rotation) );
|
||
|
savefile->Read( &rotationSpeed, sizeof(rotationSpeed) );
|
||
|
savefile->Read( &velocity, sizeof(velocity) );
|
||
|
|
||
|
savefile->Read( &fadeIn, sizeof(fadeIn) );
|
||
|
savefile->Read( &fadeOut, sizeof(fadeOut) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
======================
|
||
|
BSEntity::SetMaterial
|
||
|
======================
|
||
|
*/
|
||
|
void BSEntity::SetMaterial(const char* name) {
|
||
|
materialName = name;
|
||
|
material = declManager->FindMaterial( name );
|
||
|
material->SetSort( SS_GUI );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
======================
|
||
|
BSEntity::SetSize
|
||
|
======================
|
||
|
*/
|
||
|
void BSEntity::SetSize( float _width, float _height ) {
|
||
|
width = _width;
|
||
|
height = _height;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
======================
|
||
|
BSEntity::SetVisible
|
||
|
======================
|
||
|
*/
|
||
|
void BSEntity::SetVisible( bool isVisible ) {
|
||
|
visible = isVisible;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
======================
|
||
|
BSEntity::Update
|
||
|
======================
|
||
|
*/
|
||
|
void BSEntity::Update( float timeslice ) {
|
||
|
|
||
|
if ( !visible ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Fades
|
||
|
if ( fadeIn && entColor.w < 1.f ) {
|
||
|
entColor.w += 1 * timeslice;
|
||
|
if ( entColor.w >= 1.f ) {
|
||
|
entColor.w = 1.f;
|
||
|
fadeIn = false;
|
||
|
}
|
||
|
}
|
||
|
if ( fadeOut && entColor.w > 0.f ) {
|
||
|
entColor.w -= 1 * timeslice;
|
||
|
if ( entColor.w <= 0.f ) {
|
||
|
entColor.w = 0.f;
|
||
|
fadeOut = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Move the entity
|
||
|
position += velocity * timeslice;
|
||
|
|
||
|
// Rotate Entity
|
||
|
rotation += rotationSpeed * timeslice;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
======================
|
||
|
BSEntity::Draw
|
||
|
======================
|
||
|
*/
|
||
|
void BSEntity::Draw(idDeviceContext *dc) {
|
||
|
if ( visible ) {
|
||
|
dc->DrawMaterialRotated( position.x, position.y, width, height, material, entColor, 1.0f, 1.0f, DEG2RAD(rotation) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
*****************************************************************************
|
||
|
* idGameBearShootWindow
|
||
|
****************************************************************************
|
||
|
*/
|
||
|
idGameBearShootWindow::idGameBearShootWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) {
|
||
|
dc = d;
|
||
|
gui = g;
|
||
|
CommonInit();
|
||
|
}
|
||
|
|
||
|
idGameBearShootWindow::idGameBearShootWindow(idUserInterfaceLocal *g) : idWindow(g) {
|
||
|
gui = g;
|
||
|
CommonInit();
|
||
|
}
|
||
|
|
||
|
idGameBearShootWindow::~idGameBearShootWindow() {
|
||
|
entities.DeleteContents(true);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::WriteToSaveGame
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::WriteToSaveGame( idFile *savefile ) {
|
||
|
idWindow::WriteToSaveGame( savefile );
|
||
|
|
||
|
gamerunning.WriteToSaveGame( savefile );
|
||
|
onFire.WriteToSaveGame( savefile );
|
||
|
onContinue.WriteToSaveGame( savefile );
|
||
|
onNewGame.WriteToSaveGame( savefile );
|
||
|
|
||
|
savefile->Write( &timeSlice, sizeof(timeSlice) );
|
||
|
savefile->Write( &timeRemaining, sizeof(timeRemaining) );
|
||
|
savefile->Write( &gameOver, sizeof(gameOver) );
|
||
|
|
||
|
savefile->Write( ¤tLevel, sizeof(currentLevel) );
|
||
|
savefile->Write( &goalsHit, sizeof(goalsHit) );
|
||
|
savefile->Write( &updateScore, sizeof(updateScore) );
|
||
|
savefile->Write( &bearHitTarget, sizeof(bearHitTarget) );
|
||
|
|
||
|
savefile->Write( &bearScale, sizeof(bearScale) );
|
||
|
savefile->Write( &bearIsShrinking, sizeof(bearIsShrinking) );
|
||
|
savefile->Write( &bearShrinkStartTime, sizeof(bearShrinkStartTime) );
|
||
|
|
||
|
savefile->Write( &turretAngle, sizeof(turretAngle) );
|
||
|
savefile->Write( &turretForce, sizeof(turretForce) );
|
||
|
|
||
|
savefile->Write( &windForce, sizeof(windForce) );
|
||
|
savefile->Write( &windUpdateTime, sizeof(windUpdateTime) );
|
||
|
|
||
|
int numberOfEnts = entities.Num();
|
||
|
savefile->Write( &numberOfEnts, sizeof(numberOfEnts) );
|
||
|
|
||
|
for ( int i=0; i<numberOfEnts; i++ ) {
|
||
|
entities[i]->WriteToSaveGame( savefile );
|
||
|
}
|
||
|
|
||
|
int index;
|
||
|
index = entities.FindIndex( turret );
|
||
|
savefile->Write( &index, sizeof(index) );
|
||
|
index = entities.FindIndex( bear );
|
||
|
savefile->Write( &index, sizeof(index) );
|
||
|
index = entities.FindIndex( helicopter );
|
||
|
savefile->Write( &index, sizeof(index) );
|
||
|
index = entities.FindIndex( goal );
|
||
|
savefile->Write( &index, sizeof(index) );
|
||
|
index = entities.FindIndex( wind );
|
||
|
savefile->Write( &index, sizeof(index) );
|
||
|
index = entities.FindIndex( gunblast );
|
||
|
savefile->Write( &index, sizeof(index) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::ReadFromSaveGame
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::ReadFromSaveGame( idFile *savefile ) {
|
||
|
idWindow::ReadFromSaveGame( savefile );
|
||
|
|
||
|
// Remove all existing entities
|
||
|
entities.DeleteContents(true);
|
||
|
|
||
|
gamerunning.ReadFromSaveGame( savefile );
|
||
|
onFire.ReadFromSaveGame( savefile );
|
||
|
onContinue.ReadFromSaveGame( savefile );
|
||
|
onNewGame.ReadFromSaveGame( savefile );
|
||
|
|
||
|
savefile->Read( &timeSlice, sizeof(timeSlice) );
|
||
|
savefile->Read( &timeRemaining, sizeof(timeRemaining) );
|
||
|
savefile->Read( &gameOver, sizeof(gameOver) );
|
||
|
|
||
|
savefile->Read( ¤tLevel, sizeof(currentLevel) );
|
||
|
savefile->Read( &goalsHit, sizeof(goalsHit) );
|
||
|
savefile->Read( &updateScore, sizeof(updateScore) );
|
||
|
savefile->Read( &bearHitTarget, sizeof(bearHitTarget) );
|
||
|
|
||
|
savefile->Read( &bearScale, sizeof(bearScale) );
|
||
|
savefile->Read( &bearIsShrinking, sizeof(bearIsShrinking) );
|
||
|
savefile->Read( &bearShrinkStartTime, sizeof(bearShrinkStartTime) );
|
||
|
|
||
|
savefile->Read( &turretAngle, sizeof(turretAngle) );
|
||
|
savefile->Read( &turretForce, sizeof(turretForce) );
|
||
|
|
||
|
savefile->Read( &windForce, sizeof(windForce) );
|
||
|
savefile->Read( &windUpdateTime, sizeof(windUpdateTime) );
|
||
|
|
||
|
int numberOfEnts;
|
||
|
savefile->Read( &numberOfEnts, sizeof(numberOfEnts) );
|
||
|
|
||
|
for ( int i=0; i<numberOfEnts; i++ ) {
|
||
|
BSEntity *ent;
|
||
|
|
||
|
ent = new BSEntity( this );
|
||
|
ent->ReadFromSaveGame( savefile, this );
|
||
|
entities.Append( ent );
|
||
|
}
|
||
|
|
||
|
int index;
|
||
|
savefile->Read( &index, sizeof(index) );
|
||
|
turret = entities[index];
|
||
|
savefile->Read( &index, sizeof(index) );
|
||
|
bear = entities[index];
|
||
|
savefile->Read( &index, sizeof(index) );
|
||
|
helicopter = entities[index];
|
||
|
savefile->Read( &index, sizeof(index) );
|
||
|
goal = entities[index];
|
||
|
savefile->Read( &index, sizeof(index) );
|
||
|
wind = entities[index];
|
||
|
savefile->Read( &index, sizeof(index) );
|
||
|
gunblast = entities[index];
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::ResetGameState
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::ResetGameState() {
|
||
|
gamerunning = false;
|
||
|
gameOver = false;
|
||
|
onFire = false;
|
||
|
onContinue = false;
|
||
|
onNewGame = false;
|
||
|
|
||
|
// Game moves forward 16 milliseconds every frame
|
||
|
timeSlice = 0.016f;
|
||
|
timeRemaining = 60.f;
|
||
|
goalsHit = 0;
|
||
|
updateScore = false;
|
||
|
bearHitTarget = false;
|
||
|
currentLevel = 1;
|
||
|
turretAngle = 0.f;
|
||
|
turretForce = 200.f;
|
||
|
windForce = 0.f;
|
||
|
windUpdateTime = 0;
|
||
|
|
||
|
bearIsShrinking = false;
|
||
|
bearShrinkStartTime = 0;
|
||
|
bearScale = 1.f;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::CommonInit
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::CommonInit() {
|
||
|
BSEntity * ent;
|
||
|
|
||
|
// Precache sounds
|
||
|
declManager->FindSound( "arcade_beargroan" );
|
||
|
declManager->FindSound( "arcade_sargeshoot" );
|
||
|
declManager->FindSound( "arcade_balloonpop" );
|
||
|
declManager->FindSound( "arcade_levelcomplete1" );
|
||
|
|
||
|
// Precache dynamically used materials
|
||
|
declManager->FindMaterial( "game/bearshoot/helicopter_broken" );
|
||
|
declManager->FindMaterial( "game/bearshoot/goal_dead" );
|
||
|
declManager->FindMaterial( "game/bearshoot/gun_blast" );
|
||
|
|
||
|
ResetGameState();
|
||
|
|
||
|
ent = new BSEntity( this );
|
||
|
turret = ent;
|
||
|
ent->SetMaterial( "game/bearshoot/turret" );
|
||
|
ent->SetSize( 272, 144 );
|
||
|
ent->position.x = -44;
|
||
|
ent->position.y = 260;
|
||
|
entities.Append( ent );
|
||
|
|
||
|
ent = new BSEntity( this );
|
||
|
ent->SetMaterial( "game/bearshoot/turret_base" );
|
||
|
ent->SetSize( 144, 160 );
|
||
|
ent->position.x = 16;
|
||
|
ent->position.y = 280;
|
||
|
entities.Append( ent );
|
||
|
|
||
|
ent = new BSEntity( this );
|
||
|
bear = ent;
|
||
|
ent->SetMaterial( "game/bearshoot/bear" );
|
||
|
ent->SetSize( BEAR_SIZE, BEAR_SIZE );
|
||
|
ent->SetVisible( false );
|
||
|
ent->position.x = 0;
|
||
|
ent->position.y = 0;
|
||
|
entities.Append( ent );
|
||
|
|
||
|
ent = new BSEntity( this );
|
||
|
helicopter = ent;
|
||
|
ent->SetMaterial( "game/bearshoot/helicopter" );
|
||
|
ent->SetSize( 64, 64 );
|
||
|
ent->position.x = 550;
|
||
|
ent->position.y = 100;
|
||
|
entities.Append( ent );
|
||
|
|
||
|
ent = new BSEntity( this );
|
||
|
goal = ent;
|
||
|
ent->SetMaterial( "game/bearshoot/goal" );
|
||
|
ent->SetSize( 64, 64 );
|
||
|
ent->position.x = 550;
|
||
|
ent->position.y = 164;
|
||
|
entities.Append( ent );
|
||
|
|
||
|
ent = new BSEntity( this );
|
||
|
wind = ent;
|
||
|
ent->SetMaterial( "game/bearshoot/wind" );
|
||
|
ent->SetSize( 100, 40 );
|
||
|
ent->position.x = 500;
|
||
|
ent->position.y = 430;
|
||
|
entities.Append( ent );
|
||
|
|
||
|
ent = new BSEntity( this );
|
||
|
gunblast = ent;
|
||
|
ent->SetMaterial( "game/bearshoot/gun_blast" );
|
||
|
ent->SetSize( 64, 64 );
|
||
|
ent->SetVisible( false );
|
||
|
entities.Append( ent );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::HandleEvent
|
||
|
=============================
|
||
|
*/
|
||
|
const char *idGameBearShootWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) {
|
||
|
int key = event->evValue;
|
||
|
|
||
|
// need to call this to allow proper focus and capturing on embedded children
|
||
|
const char *ret = idWindow::HandleEvent(event, updateVisuals);
|
||
|
|
||
|
if ( event->evType == SE_KEY ) {
|
||
|
|
||
|
if ( !event->evValue2 ) {
|
||
|
return ret;
|
||
|
}
|
||
|
if ( key == K_MOUSE1) {
|
||
|
// Mouse was clicked
|
||
|
} else {
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::ParseInternalVar
|
||
|
=============================
|
||
|
*/
|
||
|
bool idGameBearShootWindow::ParseInternalVar(const char *_name, idParser *src) {
|
||
|
if ( idStr::Icmp(_name, "gamerunning") == 0 ) {
|
||
|
gamerunning = src->ParseBool();
|
||
|
return true;
|
||
|
}
|
||
|
if ( idStr::Icmp(_name, "onFire") == 0 ) {
|
||
|
onFire = src->ParseBool();
|
||
|
return true;
|
||
|
}
|
||
|
if ( idStr::Icmp(_name, "onContinue") == 0 ) {
|
||
|
onContinue = src->ParseBool();
|
||
|
return true;
|
||
|
}
|
||
|
if ( idStr::Icmp(_name, "onNewGame") == 0 ) {
|
||
|
onNewGame = src->ParseBool();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return idWindow::ParseInternalVar(_name, src);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::GetWinVarByName
|
||
|
=============================
|
||
|
*/
|
||
|
idWinVar *idGameBearShootWindow::GetWinVarByName(const char *_name, bool winLookup, drawWin_t** owner) {
|
||
|
idWinVar *retVar = NULL;
|
||
|
|
||
|
if ( idStr::Icmp(_name, "gamerunning") == 0 ) {
|
||
|
retVar = &gamerunning;
|
||
|
} else if ( idStr::Icmp(_name, "onFire") == 0 ) {
|
||
|
retVar = &onFire;
|
||
|
} else if ( idStr::Icmp(_name, "onContinue") == 0 ) {
|
||
|
retVar = &onContinue;
|
||
|
} else if ( idStr::Icmp(_name, "onNewGame") == 0 ) {
|
||
|
retVar = &onNewGame;
|
||
|
}
|
||
|
|
||
|
if(retVar) {
|
||
|
return retVar;
|
||
|
}
|
||
|
|
||
|
return idWindow::GetWinVarByName(_name, winLookup, owner);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::PostParse
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::PostParse() {
|
||
|
idWindow::PostParse();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::Draw
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::Draw(int time, float x, float y) {
|
||
|
int i;
|
||
|
|
||
|
//Update the game every frame before drawing
|
||
|
UpdateGame();
|
||
|
|
||
|
for( i = entities.Num()-1; i >= 0; i-- ) {
|
||
|
entities[i]->Draw(dc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::Activate
|
||
|
=============================
|
||
|
*/
|
||
|
const char *idGameBearShootWindow::Activate(bool activate) {
|
||
|
return "";
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::UpdateTurret
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::UpdateTurret() {
|
||
|
idVec2 pt;
|
||
|
idVec2 turretOrig;
|
||
|
idVec2 right;
|
||
|
float dot, angle;
|
||
|
|
||
|
pt.x = gui->CursorX();
|
||
|
pt.y = gui->CursorY();
|
||
|
turretOrig.Set( 80.f, 348.f );
|
||
|
|
||
|
pt = pt - turretOrig;
|
||
|
pt.NormalizeFast();
|
||
|
|
||
|
right.x = 1.f;
|
||
|
right.y = 0.f;
|
||
|
|
||
|
dot = pt * right;
|
||
|
|
||
|
angle = RAD2DEG( acosf( dot ) );
|
||
|
|
||
|
turretAngle = idMath::ClampFloat( 0.f, 90.f, angle );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::UpdateBear
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::UpdateBear() {
|
||
|
int time = gui->GetTime();
|
||
|
bool startShrink = false;
|
||
|
|
||
|
// Apply gravity
|
||
|
bear->velocity.y += BEAR_GRAVITY * timeSlice;
|
||
|
|
||
|
// Apply wind
|
||
|
bear->velocity.x += windForce * timeSlice;
|
||
|
|
||
|
// Check for collisions
|
||
|
if ( !bearHitTarget && !gameOver ) {
|
||
|
idVec2 bearCenter;
|
||
|
bool collision = false;
|
||
|
|
||
|
bearCenter.x = bear->position.x + bear->width/2;
|
||
|
bearCenter.y = bear->position.y + bear->height/2;
|
||
|
|
||
|
if ( bearCenter.x > (helicopter->position.x + 16) && bearCenter.x < (helicopter->position.x + helicopter->width - 29) ) {
|
||
|
if ( bearCenter.y > (helicopter->position.y + 12) && bearCenter.y < (helicopter->position.y + helicopter->height - 7) ) {
|
||
|
collision = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( collision ) {
|
||
|
// balloons pop and bear tumbles to ground
|
||
|
helicopter->SetMaterial( "game/bearshoot/helicopter_broken" );
|
||
|
helicopter->velocity.y = 230.f;
|
||
|
goal->velocity.y = 230.f;
|
||
|
session->sw->PlayShaderDirectly( "arcade_balloonpop" );
|
||
|
|
||
|
bear->SetVisible( false );
|
||
|
if ( bear->velocity.x > 0 ) {
|
||
|
bear->velocity.x *= -1.f;
|
||
|
}
|
||
|
bear->velocity *= 0.666f;
|
||
|
bearHitTarget = true;
|
||
|
updateScore = true;
|
||
|
startShrink = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check for ground collision
|
||
|
if ( bear->position.y > 380 ) {
|
||
|
bear->position.y = 380;
|
||
|
|
||
|
if ( bear->velocity.Length() < 25 ) {
|
||
|
bear->velocity.Zero();
|
||
|
} else {
|
||
|
startShrink = true;
|
||
|
|
||
|
bear->velocity.y *= -1.f;
|
||
|
bear->velocity *= 0.5f;
|
||
|
|
||
|
if ( bearScale ) {
|
||
|
session->sw->PlayShaderDirectly( "arcade_balloonpop" );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Bear rotation is based on velocity
|
||
|
float angle;
|
||
|
idVec2 dir;
|
||
|
|
||
|
dir = bear->velocity;
|
||
|
dir.NormalizeFast();
|
||
|
|
||
|
angle = RAD2DEG( atan2( dir.x, dir.y ) );
|
||
|
bear->rotation = angle - 90;
|
||
|
|
||
|
// Update Bear scale
|
||
|
if ( bear->position.x > 650 ) {
|
||
|
startShrink = true;
|
||
|
}
|
||
|
|
||
|
if ( !bearIsShrinking && bearScale && startShrink ) {
|
||
|
bearShrinkStartTime = time;
|
||
|
bearIsShrinking = true;
|
||
|
}
|
||
|
|
||
|
if ( bearIsShrinking ) {
|
||
|
if ( bearHitTarget ) {
|
||
|
bearScale = 1 - ( (float)(time - bearShrinkStartTime) / BEAR_SHRINK_TIME );
|
||
|
} else {
|
||
|
bearScale = 1 - ( (float)(time - bearShrinkStartTime) / 750 );
|
||
|
}
|
||
|
bearScale *= BEAR_SIZE;
|
||
|
bear->SetSize( bearScale, bearScale );
|
||
|
|
||
|
if ( bearScale < 0 ) {
|
||
|
gui->HandleNamedEvent( "EnableFireButton" );
|
||
|
bearIsShrinking = false;
|
||
|
bearScale = 0.f;
|
||
|
|
||
|
if ( bearHitTarget ) {
|
||
|
goal->SetMaterial( "game/bearshoot/goal" );
|
||
|
goal->position.x = 550;
|
||
|
goal->position.y = 164;
|
||
|
goal->velocity.Zero();
|
||
|
goal->velocity.y = (currentLevel-1) * 30;
|
||
|
goal->entColor.w = 0.f;
|
||
|
goal->fadeIn = true;
|
||
|
goal->fadeOut = false;
|
||
|
|
||
|
helicopter->SetVisible( true );
|
||
|
helicopter->SetMaterial( "game/bearshoot/helicopter" );
|
||
|
helicopter->position.x = 550;
|
||
|
helicopter->position.y = 100;
|
||
|
helicopter->velocity.Zero();
|
||
|
helicopter->velocity.y = goal->velocity.y;
|
||
|
helicopter->entColor.w = 0.f;
|
||
|
helicopter->fadeIn = true;
|
||
|
helicopter->fadeOut = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::UpdateHelicopter
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::UpdateHelicopter() {
|
||
|
|
||
|
if ( bearHitTarget && bearIsShrinking ) {
|
||
|
if ( helicopter->velocity.y != 0 && helicopter->position.y > 264 ) {
|
||
|
helicopter->velocity.y = 0;
|
||
|
goal->velocity.y = 0;
|
||
|
|
||
|
helicopter->SetVisible( false );
|
||
|
goal->SetMaterial( "game/bearshoot/goal_dead" );
|
||
|
session->sw->PlayShaderDirectly( "arcade_beargroan", 1 );
|
||
|
|
||
|
helicopter->fadeOut = true;
|
||
|
goal->fadeOut = true;
|
||
|
}
|
||
|
} else if ( currentLevel > 1 ) {
|
||
|
int height = helicopter->position.y;
|
||
|
float speed = (currentLevel-1) * 30;
|
||
|
|
||
|
if ( height > 240 ) {
|
||
|
helicopter->velocity.y = -speed;
|
||
|
goal->velocity.y = -speed;
|
||
|
} else if ( height < 30 ) {
|
||
|
helicopter->velocity.y = speed;
|
||
|
goal->velocity.y = speed;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::UpdateButtons
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::UpdateButtons() {
|
||
|
|
||
|
if ( onFire ) {
|
||
|
idVec2 vec;
|
||
|
|
||
|
gui->HandleNamedEvent( "DisableFireButton" );
|
||
|
session->sw->PlayShaderDirectly( "arcade_sargeshoot" );
|
||
|
|
||
|
bear->SetVisible( true );
|
||
|
bearScale = 1.f;
|
||
|
bear->SetSize( BEAR_SIZE, BEAR_SIZE );
|
||
|
|
||
|
vec.x = idMath::Cos( DEG2RAD(turretAngle) );
|
||
|
vec.x += ( 1 - vec.x ) * 0.18f;
|
||
|
vec.y = -idMath::Sin( DEG2RAD(turretAngle) );
|
||
|
|
||
|
turretForce = bearTurretForce.GetFloat();
|
||
|
|
||
|
bear->position.x = 80 + ( 96 * vec.x );
|
||
|
bear->position.y = 334 + ( 96 * vec.y );
|
||
|
bear->velocity.x = vec.x * turretForce;
|
||
|
bear->velocity.y = vec.y * turretForce;
|
||
|
|
||
|
gunblast->position.x = 55 + ( 96 * vec.x );
|
||
|
gunblast->position.y = 310 + ( 100 * vec.y );
|
||
|
gunblast->SetVisible( true );
|
||
|
gunblast->entColor.w = 1.f;
|
||
|
gunblast->rotation = turretAngle;
|
||
|
gunblast->fadeOut = true;
|
||
|
|
||
|
bearHitTarget = false;
|
||
|
|
||
|
onFire = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::UpdateScore
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::UpdateScore() {
|
||
|
|
||
|
if ( gameOver ) {
|
||
|
gui->HandleNamedEvent( "GameOver" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
goalsHit++;
|
||
|
gui->SetStateString( "player_score", va("%i", goalsHit ) );
|
||
|
|
||
|
// Check for level progression
|
||
|
if ( !(goalsHit % 5) ) {
|
||
|
currentLevel++;
|
||
|
gui->SetStateString( "current_level", va("%i", currentLevel ) );
|
||
|
session->sw->PlayShaderDirectly( "arcade_levelcomplete1", 3 );
|
||
|
|
||
|
timeRemaining += 30;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============================
|
||
|
idGameBearShootWindow::UpdateGame
|
||
|
=============================
|
||
|
*/
|
||
|
void idGameBearShootWindow::UpdateGame() {
|
||
|
int i;
|
||
|
|
||
|
if ( onNewGame ) {
|
||
|
ResetGameState();
|
||
|
|
||
|
goal->position.x = 550;
|
||
|
goal->position.y = 164;
|
||
|
goal->velocity.Zero();
|
||
|
helicopter->position.x = 550;
|
||
|
helicopter->position.y = 100;
|
||
|
helicopter->velocity.Zero();
|
||
|
bear->SetVisible( false );
|
||
|
|
||
|
bearTurretAngle.SetFloat( 0.f );
|
||
|
bearTurretForce.SetFloat( 200.f );
|
||
|
|
||
|
gamerunning = true;
|
||
|
}
|
||
|
if ( onContinue ) {
|
||
|
gameOver = false;
|
||
|
timeRemaining = 60.f;
|
||
|
|
||
|
onContinue = false;
|
||
|
}
|
||
|
|
||
|
if(gamerunning == true) {
|
||
|
int current_time = gui->GetTime();
|
||
|
idRandom rnd( current_time );
|
||
|
|
||
|
// Check for button presses
|
||
|
UpdateButtons();
|
||
|
|
||
|
if ( bear ) {
|
||
|
UpdateBear();
|
||
|
}
|
||
|
if ( helicopter && goal ) {
|
||
|
UpdateHelicopter();
|
||
|
}
|
||
|
|
||
|
// Update Wind
|
||
|
if ( windUpdateTime < current_time ) {
|
||
|
float scale;
|
||
|
int width;
|
||
|
|
||
|
windForce = rnd.CRandomFloat() * ( MAX_WINDFORCE * 0.75f );
|
||
|
if (windForce > 0) {
|
||
|
windForce += ( MAX_WINDFORCE * 0.25f );
|
||
|
wind->rotation = 0;
|
||
|
} else {
|
||
|
windForce -= ( MAX_WINDFORCE * 0.25f );
|
||
|
wind->rotation = 180;
|
||
|
}
|
||
|
|
||
|
scale = 1.f - (( MAX_WINDFORCE - idMath::Fabs(windForce) ) / MAX_WINDFORCE);
|
||
|
width = 100*scale;
|
||
|
|
||
|
if ( windForce < 0 ) {
|
||
|
wind->position.x = 500 - width + 1;
|
||
|
} else {
|
||
|
wind->position.x = 500;
|
||
|
}
|
||
|
wind->SetSize( width, 40 );
|
||
|
|
||
|
windUpdateTime = current_time + 7000 + rnd.RandomInt(5000);
|
||
|
}
|
||
|
|
||
|
// Update turret rotation angle
|
||
|
if ( turret ) {
|
||
|
turretAngle = bearTurretAngle.GetFloat();
|
||
|
turret->rotation = turretAngle;
|
||
|
}
|
||
|
|
||
|
for( i = 0; i < entities.Num(); i++ ) {
|
||
|
entities[i]->Update( timeSlice );
|
||
|
}
|
||
|
|
||
|
// Update countdown timer
|
||
|
timeRemaining -= timeSlice;
|
||
|
timeRemaining = idMath::ClampFloat( 0.f, 99999.f, timeRemaining );
|
||
|
gui->SetStateString( "time_remaining", va("%2.1f", timeRemaining ) );
|
||
|
|
||
|
if ( timeRemaining <= 0.f && !gameOver ) {
|
||
|
gameOver = true;
|
||
|
updateScore = true;
|
||
|
}
|
||
|
|
||
|
if ( updateScore ) {
|
||
|
UpdateScore();
|
||
|
updateScore = false;
|
||
|
}
|
||
|
}
|
||
|
}
|