1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition 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 BFG Edition 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 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition 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 BFG Edition 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.
- ===========================================================================
- */
- #pragma hdrstop
- #include "../idlib/precompiled.h"
- #include "DeviceContext.h"
- #include "Window.h"
- #include "UserInterfaceLocal.h"
- #include "GameSSDWindow.h"
- #define Z_NEAR 100.0f
- #define Z_FAR 4000.0f
- #define ENTITY_START_DIST 3000
- #define V_WIDTH 640.0f
- #define V_HEIGHT 480.0f
- /*
- *****************************************************************************
- * SSDCrossHair
- ****************************************************************************
- */
- #define CROSSHAIR_STANDARD_MATERIAL "game/SSD/crosshair_standard"
- #define CROSSHAIR_SUPER_MATERIAL "game/SSD/crosshair_super"
- SSDCrossHair::SSDCrossHair() {
- }
- SSDCrossHair::~SSDCrossHair() {
- }
- void SSDCrossHair::WriteToSaveGame( idFile *savefile ) {
-
- savefile->Write(¤tCrosshair, sizeof(currentCrosshair));
- savefile->Write(&crosshairWidth, sizeof(crosshairWidth));
- savefile->Write(&crosshairHeight, sizeof(crosshairHeight));
- }
- void SSDCrossHair::ReadFromSaveGame( idFile *savefile ) {
- InitCrosshairs();
- savefile->Read(¤tCrosshair, sizeof(currentCrosshair));
- savefile->Read(&crosshairWidth, sizeof(crosshairWidth));
- savefile->Read(&crosshairHeight, sizeof(crosshairHeight));
- }
- void SSDCrossHair::InitCrosshairs() {
-
- crosshairMaterial[CROSSHAIR_STANDARD] = declManager->FindMaterial( CROSSHAIR_STANDARD_MATERIAL );
- crosshairMaterial[CROSSHAIR_SUPER] = declManager->FindMaterial( CROSSHAIR_SUPER_MATERIAL );
- crosshairWidth = 64;
- crosshairHeight = 64;
- currentCrosshair = CROSSHAIR_STANDARD;
- }
- void SSDCrossHair::Draw(const idVec2& cursor) {
- float x,y;
- x = cursor.x-(crosshairWidth/2);
- y = cursor.y-(crosshairHeight/2);
- dc->DrawMaterial(x, y, crosshairWidth, crosshairHeight, crosshairMaterial[currentCrosshair], colorWhite, 1.0f, 1.0f);
-
- }
- /*
- *****************************************************************************
- * SSDEntity
- ****************************************************************************
- */
- SSDEntity::SSDEntity() {
- EntityInit();
- }
- SSDEntity::~SSDEntity() {
- }
- void SSDEntity::WriteToSaveGame( idFile *savefile ) {
-
- savefile->Write(&type, sizeof(type));
- game->WriteSaveGameString(materialName, savefile);
- savefile->Write(&position, sizeof(position));
- savefile->Write(&size, sizeof(size));
- savefile->Write(&radius, sizeof(radius));
- savefile->Write(&hitRadius, sizeof(hitRadius));
- savefile->Write(&rotation, sizeof(rotation));
- savefile->Write(&matColor, sizeof(matColor));
-
- game->WriteSaveGameString(text, savefile);
- savefile->Write(&textScale, sizeof(textScale));
- savefile->Write(&foreColor, sizeof(foreColor));
-
- savefile->Write(¤tTime, sizeof(currentTime));
- savefile->Write(&lastUpdate, sizeof(lastUpdate));
- savefile->Write(&elapsed, sizeof(elapsed));
- savefile->Write(&destroyed, sizeof(destroyed));
- savefile->Write(&noHit, sizeof(noHit));
- savefile->Write(&noPlayerDamage, sizeof(noPlayerDamage));
- savefile->Write(&inUse, sizeof(inUse));
- }
- void SSDEntity::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) {
- savefile->Read(&type, sizeof(type));
- game->ReadSaveGameString(materialName, savefile);
- SetMaterial(materialName);
- savefile->Read(&position, sizeof(position));
- savefile->Read(&size, sizeof(size));
- savefile->Read(&radius, sizeof(radius));
- savefile->Read(&hitRadius, sizeof(hitRadius));
- savefile->Read(&rotation, sizeof(rotation));
- savefile->Read(&matColor, sizeof(matColor));
- game->ReadSaveGameString(text, savefile);
- savefile->Read(&textScale, sizeof(textScale));
- savefile->Read(&foreColor, sizeof(foreColor));
- game = _game;
- savefile->Read(¤tTime, sizeof(currentTime));
- savefile->Read(&lastUpdate, sizeof(lastUpdate));
- savefile->Read(&elapsed, sizeof(elapsed));
- savefile->Read(&destroyed, sizeof(destroyed));
- savefile->Read(&noHit, sizeof(noHit));
- savefile->Read(&noPlayerDamage, sizeof(noPlayerDamage));
- savefile->Read(&inUse, sizeof(inUse));
- }
- void SSDEntity::EntityInit() {
- inUse = false;
- type = SSD_ENTITY_BASE;
-
- materialName = "";
- material = NULL;
- position.Zero();
- size.Zero();
- radius = 0.0f;
- hitRadius = 0.0f;
- rotation = 0.0f;
- currentTime = 0;
- lastUpdate = 0;
- destroyed = false;
- noHit = false;
- noPlayerDamage = false;
- matColor.Set(1, 1, 1, 1);
- text = "";
- textScale = 1.0f;
- foreColor.Set(1, 1, 1, 1);
- }
- void SSDEntity::SetGame(idGameSSDWindow* _game) {
- game = _game;
- }
- void SSDEntity::SetMaterial(const char* name) {
- materialName = name;
- material = declManager->FindMaterial( name );
- material->SetSort( SS_GUI );
- }
- void SSDEntity::SetPosition(const idVec3& _position) {
- position = _position;
- }
- void SSDEntity::SetSize(const idVec2& _size) {
- size = _size;
- }
- void SSDEntity::SetRadius(float _radius, float _hitFactor) {
- radius = _radius;
- hitRadius = _radius*_hitFactor;
- }
- void SSDEntity::SetRotation(float _rotation) {
- rotation = _rotation;
- }
- void SSDEntity::Update() {
- currentTime = game->ssdTime;
- //Is this the first update
- if(lastUpdate == 0) {
- lastUpdate = currentTime;
- return;
- }
- elapsed = currentTime - lastUpdate;
- EntityUpdate();
- lastUpdate = currentTime;
- }
- bool SSDEntity::HitTest(const idVec2& pt) {
- if(noHit) {
- return false;
- }
- idVec3 screenPos = WorldToScreen(position);
- //Scale the radius based on the distance from the player
- float scale = 1.0f -((screenPos.z-Z_NEAR)/(Z_FAR-Z_NEAR));
- float scaledRad = scale*hitRadius;
- //So we can compare against the square of the length between two points
- float scaleRadSqr = scaledRad*scaledRad;
- idVec2 diff = screenPos.ToVec2()-pt;
- float dist = idMath::Fabs(diff.LengthSqr());
- if(dist < scaleRadSqr) {
- return true;
- }
- return false;
- }
- void SSDEntity::Draw() {
- idVec2 persize;
- float x,y;
- idBounds bounds;
- bounds[0] = idVec3(position.x - (size.x/2.0f), position.y - (size.y/2.0f), position.z);
- bounds[1] = idVec3(position.x + (size.x/2.0f), position.y + (size.y/2.0f), position.z);
- idBounds screenBounds = WorldToScreen(bounds);
- persize.x = idMath::Fabs(screenBounds[1].x - screenBounds[0].x);
- persize.y = idMath::Fabs(screenBounds[1].y - screenBounds[0].y);
- idVec3 center = screenBounds.GetCenter();
- x = screenBounds[0].x;
- y = screenBounds[1].y;
- dc->DrawMaterialRotated(x, y, persize.x, persize.y, material, matColor, 1.0f, 1.0f, DEG2RAD(rotation));
- if(text.Length() > 0) {
- idRectangle rect( x, y, VIRTUAL_WIDTH, VIRTUAL_HEIGHT );
- dc->DrawText( text, textScale, 0, foreColor, rect, false );
- }
- }
- void SSDEntity::DestroyEntity() {
- inUse = false;
- }
- idBounds SSDEntity::WorldToScreen(const idBounds worldBounds) {
- idVec3 screenMin = WorldToScreen(worldBounds[0]);
- idVec3 screenMax = WorldToScreen(worldBounds[1]);
- idBounds screenBounds(screenMin, screenMax);
- return screenBounds;
- }
- idVec3 SSDEntity::WorldToScreen(const idVec3& worldPos) {
-
- float d = 0.5f*V_WIDTH*idMath::Tan(DEG2RAD(90.0f)/2.0f);
- //World To Camera Coordinates
- idVec3 cameraTrans(0,0,d);
- idVec3 cameraPos;
- cameraPos = worldPos + cameraTrans;
- //Camera To Screen Coordinates
- idVec3 screenPos;
- screenPos.x = d*cameraPos.x/cameraPos.z + (0.5f*V_WIDTH-0.5f);
- screenPos.y = -d*cameraPos.y/cameraPos.z + (0.5f*V_HEIGHT-0.5f);
- screenPos.z = cameraPos.z;
- return screenPos;
- }
- idVec3 SSDEntity::ScreenToWorld(const idVec3& screenPos) {
- idVec3 worldPos;
- worldPos.x = screenPos.x - 0.5f * V_WIDTH;
- worldPos.y = -(screenPos.y - 0.5f * V_HEIGHT);
- worldPos.z = screenPos.z;
- return worldPos;
- }
- /*
- *****************************************************************************
- * SSDMover
- ****************************************************************************
- */
- SSDMover::SSDMover() {
- }
- SSDMover::~SSDMover() {
- }
- void SSDMover::WriteToSaveGame( idFile *savefile ) {
- SSDEntity::WriteToSaveGame(savefile);
-
- savefile->Write(&speed, sizeof(speed));
- savefile->Write(&rotationSpeed, sizeof(rotationSpeed));
- }
- void SSDMover::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) {
- SSDEntity::ReadFromSaveGame(savefile, _game);
- savefile->Read(&speed, sizeof(speed));
- savefile->Read(&rotationSpeed, sizeof(rotationSpeed));
- }
- void SSDMover::MoverInit(const idVec3& _speed, float _rotationSpeed) {
-
- speed = _speed;
- rotationSpeed = _rotationSpeed;
- }
- void SSDMover::EntityUpdate() {
-
- SSDEntity::EntityUpdate();
- //Move forward based on speed (units per second)
- idVec3 moved = ((float)elapsed/1000.0f)*speed;
- position += moved;
- float rotated = ((float)elapsed/1000.0f)*rotationSpeed*360.0f;
- rotation += rotated;
- if(rotation >= 360) {
- rotation -= 360.0f;
- }
- if(rotation < 0) {
- rotation += 360.0f;
- }
- }
- /*
- *****************************************************************************
- * SSDAsteroid
- ****************************************************************************
- */
- SSDAsteroid SSDAsteroid::asteroidPool[MAX_ASTEROIDS];
- #define ASTEROID_MATERIAL "game/SSD/asteroid"
- SSDAsteroid::SSDAsteroid() {
- }
- SSDAsteroid::~SSDAsteroid() {
- }
- void SSDAsteroid::WriteToSaveGame( idFile *savefile ) {
- SSDMover::WriteToSaveGame(savefile);
- savefile->Write(&health, sizeof(health));
- }
- void SSDAsteroid::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) {
- SSDMover::ReadFromSaveGame(savefile, _game);
- savefile->Read(&health, sizeof(health));
- }
- void SSDAsteroid::Init(idGameSSDWindow* _game, const idVec3& startPosition, const idVec2& _size, float _speed, float rotate, int _health) {
- EntityInit();
- MoverInit(idVec3(0,0, -_speed), rotate);
-
- SetGame(_game);
- type = SSD_ENTITY_ASTEROID;
- SetMaterial(ASTEROID_MATERIAL);
- SetSize(_size);
- SetRadius(Max(size.x, size.y), 0.3f);
- SetRotation(game->random.RandomInt(360));
-
- position = startPosition;
- health = _health;
- }
- void SSDAsteroid::EntityUpdate() {
-
- SSDMover::EntityUpdate();
- }
- SSDAsteroid* SSDAsteroid::GetNewAsteroid(idGameSSDWindow* _game, const idVec3& startPosition, const idVec2& _size, float _speed, float rotate, int _health) {
- for(int i = 0; i < MAX_ASTEROIDS; i++) {
- if(!asteroidPool[i].inUse) {
- asteroidPool[i].Init(_game, startPosition, _size, _speed, rotate, _health);
- asteroidPool[i].inUse = true;
- asteroidPool[i].id = i;
- return &asteroidPool[i];
- }
- }
- return NULL;
- }
- SSDAsteroid* SSDAsteroid::GetSpecificAsteroid(int id) {
- return &asteroidPool[id];
- }
- void SSDAsteroid::WriteAsteroids(idFile* savefile) {
- int count = 0;
- for(int i = 0; i < MAX_ASTEROIDS; i++) {
- if(asteroidPool[i].inUse) {
- count++;
- }
- }
- savefile->Write(&count, sizeof(count));
- for(int i = 0; i < MAX_ASTEROIDS; i++) {
- if(asteroidPool[i].inUse) {
- savefile->Write(&(asteroidPool[i].id), sizeof(asteroidPool[i].id));
- asteroidPool[i].WriteToSaveGame(savefile);
- }
- }
- }
- void SSDAsteroid::ReadAsteroids( idFile* savefile, idGameSSDWindow* _game) {
-
- int count;
- savefile->Read(&count, sizeof(count));
- for(int i = 0; i < count; i++) {
- int id;
- savefile->Read(&id, sizeof(id));
- SSDAsteroid* ent = GetSpecificAsteroid(id);
- ent->ReadFromSaveGame(savefile, _game);
- }
- }
- /*
- *****************************************************************************
- * SSDAstronaut
- ****************************************************************************
- */
- SSDAstronaut SSDAstronaut::astronautPool[MAX_ASTRONAUT];
- #define ASTRONAUT_MATERIAL "game/SSD/astronaut"
- SSDAstronaut::SSDAstronaut() {
- }
- SSDAstronaut::~SSDAstronaut() {
- }
- void SSDAstronaut::WriteToSaveGame( idFile *savefile ) {
- SSDMover::WriteToSaveGame(savefile);
- savefile->Write(&health, sizeof(health));
- }
- void SSDAstronaut::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) {
- SSDMover::ReadFromSaveGame(savefile, _game);
- savefile->Read(&health, sizeof(health));
- }
- void SSDAstronaut::Init(idGameSSDWindow* _game, const idVec3& startPosition, float _speed, float rotate, int _health) {
- EntityInit();
- MoverInit(idVec3(0,0, -_speed), rotate);
- SetGame(_game);
- type = SSD_ENTITY_ASTRONAUT;
- SetMaterial(ASTRONAUT_MATERIAL);
- SetSize(idVec2(256,256));
- SetRadius(Max(size.x, size.y), 0.3f);
- SetRotation(game->random.RandomInt(360));
-
- position = startPosition;
- health = _health;
- }
- SSDAstronaut* SSDAstronaut::GetNewAstronaut(idGameSSDWindow* _game, const idVec3& startPosition, float _speed, float rotate, int _health) {
- for(int i = 0; i < MAX_ASTRONAUT; i++) {
- if(!astronautPool[i].inUse) {
- astronautPool[i].Init(_game, startPosition, _speed, rotate, _health);
- astronautPool[i].inUse = true;
- astronautPool[i].id = i;
- return &astronautPool[i];
- }
- }
- return NULL;
- }
- SSDAstronaut* SSDAstronaut::GetSpecificAstronaut(int id) {
- return &astronautPool[id];
-
- }
- void SSDAstronaut::WriteAstronauts(idFile* savefile) {
- int count = 0;
- for(int i = 0; i < MAX_ASTRONAUT; i++) {
- if(astronautPool[i].inUse) {
- count++;
- }
- }
- savefile->Write(&count, sizeof(count));
- for(int i = 0; i < MAX_ASTRONAUT; i++) {
- if(astronautPool[i].inUse) {
- savefile->Write(&(astronautPool[i].id), sizeof(astronautPool[i].id));
- astronautPool[i].WriteToSaveGame(savefile);
- }
- }
- }
- void SSDAstronaut::ReadAstronauts(idFile* savefile, idGameSSDWindow* _game) {
- int count;
- savefile->Read(&count, sizeof(count));
- for(int i = 0; i < count; i++) {
- int id;
- savefile->Read(&id, sizeof(id));
- SSDAstronaut* ent = GetSpecificAstronaut(id);
- ent->ReadFromSaveGame(savefile, _game);
- }
- }
- /*
- *****************************************************************************
- * SSDExplosion
- ****************************************************************************
- */
- SSDExplosion SSDExplosion::explosionPool[MAX_EXPLOSIONS];
- //#define EXPLOSION_MATERIAL "game/SSD/fball"
- //#define EXPLOSION_TELEPORT "game/SSD/teleport"
- const char* explosionMaterials[] = {
- "game/SSD/fball",
- "game/SSD/teleport"
- };
- #define EXPLOSION_MATERIAL_COUNT 2
- SSDExplosion::SSDExplosion() {
- type = SSD_ENTITY_EXPLOSION;
- }
- SSDExplosion::~SSDExplosion() {
- }
- void SSDExplosion::WriteToSaveGame( idFile *savefile ) {
- SSDEntity::WriteToSaveGame(savefile);
- savefile->Write(&finalSize, sizeof(finalSize));
- savefile->Write(&length, sizeof(length));
- savefile->Write(&beginTime, sizeof(beginTime));
- savefile->Write(&endTime, sizeof(endTime));
- savefile->Write(&explosionType, sizeof(explosionType));
-
- savefile->Write(&(buddy->type), sizeof(buddy->type));
- savefile->Write(&(buddy->id), sizeof(buddy->id));
- savefile->Write(&killBuddy, sizeof(killBuddy));
- savefile->Write(&followBuddy, sizeof(followBuddy));
- }
- void SSDExplosion::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) {
- SSDEntity::ReadFromSaveGame(savefile, _game);
- savefile->Read(&finalSize, sizeof(finalSize));
- savefile->Read(&length, sizeof(length));
- savefile->Read(&beginTime, sizeof(beginTime));
- savefile->Read(&endTime, sizeof(endTime));
- savefile->Read(&explosionType, sizeof(explosionType));
- int type, id;
- savefile->Read(&type, sizeof(type));
- savefile->Read(&id, sizeof(id));
- //Get a pointer to my buddy
- buddy = _game->GetSpecificEntity(type, id);
- savefile->Read(&killBuddy, sizeof(killBuddy));
- savefile->Read(&followBuddy, sizeof(followBuddy));
- }
- void SSDExplosion::Init(idGameSSDWindow* _game, const idVec3& _position, const idVec2& _size, int _length, int _type, SSDEntity* _buddy, bool _killBuddy, bool _followBuddy) {
-
- EntityInit();
- SetGame(_game);
- type = SSD_ENTITY_EXPLOSION;
- explosionType = _type;
- SetMaterial(explosionMaterials[explosionType]);
- SetPosition(_position);
- position.z -= 50;
- finalSize = _size;
- length = _length;
- beginTime = game->ssdTime;
- endTime = beginTime + length;
- buddy = _buddy;
- killBuddy = _killBuddy;
- followBuddy = _followBuddy;
- //Explosion Starts from nothing and will increase in size until it gets to final size
- size.Zero();
- noPlayerDamage = true;
- noHit = true;
- }
- void SSDExplosion::EntityUpdate() {
-
- SSDEntity::EntityUpdate();
- //Always set my position to my buddies position except change z to be on top
- if(followBuddy) {
- position = buddy->position;
- position.z -= 50;
- } else {
- //Only mess with the z if we are not following
- position.z = buddy->position.z - 50;
- }
- //Scale the image based on the time
- size = finalSize*((float)(currentTime-beginTime)/(float)length);
- //Destroy myself after the explosion is done
- if(currentTime > endTime) {
- destroyed = true;
-
- if(killBuddy) {
- //Destroy the exploding object
- buddy->destroyed = true;
- }
- }
- }
- SSDExplosion* SSDExplosion::GetNewExplosion(idGameSSDWindow* _game, const idVec3& _position, const idVec2& _size, int _length, int _type, SSDEntity* _buddy, bool _killBuddy, bool _followBuddy) {
- for(int i = 0; i < MAX_EXPLOSIONS; i++) {
- if(!explosionPool[i].inUse) {
- explosionPool[i].Init(_game, _position, _size, _length, _type, _buddy, _killBuddy, _followBuddy);
- explosionPool[i].inUse = true;
- return &explosionPool[i];
- }
- }
- return NULL;
- }
- SSDExplosion* SSDExplosion::GetSpecificExplosion(int id) {
- return &explosionPool[id];
- }
- void SSDExplosion::WriteExplosions(idFile* savefile) {
- int count = 0;
- for(int i = 0; i < MAX_EXPLOSIONS; i++) {
- if(explosionPool[i].inUse) {
- count++;
- }
- }
- savefile->Write(&count, sizeof(count));
- for(int i = 0; i < MAX_EXPLOSIONS; i++) {
- if(explosionPool[i].inUse) {
- savefile->Write(&(explosionPool[i].id), sizeof(explosionPool[i].id));
- explosionPool[i].WriteToSaveGame(savefile);
- }
- }
- }
- void SSDExplosion::ReadExplosions(idFile* savefile, idGameSSDWindow* _game) {
- int count;
- savefile->Read(&count, sizeof(count));
- for(int i = 0; i < count; i++) {
- int id;
- savefile->Read(&id, sizeof(id));
- SSDExplosion* ent = GetSpecificExplosion(id);
- ent->ReadFromSaveGame(savefile, _game);
- }
- }
- /*
- *****************************************************************************
- * SSDPoints
- ****************************************************************************
- */
- SSDPoints SSDPoints::pointsPool[MAX_POINTS];
- SSDPoints::SSDPoints() {
- type = SSD_ENTITY_POINTS;
- }
- SSDPoints::~SSDPoints() {
- }
- void SSDPoints::WriteToSaveGame( idFile *savefile ) {
- SSDEntity::WriteToSaveGame(savefile);
- savefile->Write(&length, sizeof(length));
- savefile->Write(&distance, sizeof(distance));
- savefile->Write(&beginTime, sizeof(beginTime));
- savefile->Write(&endTime, sizeof(endTime));
- savefile->Write(&beginPosition, sizeof(beginPosition));
- savefile->Write(&endPosition, sizeof(endPosition));
- savefile->Write(&beginColor, sizeof(beginColor));
- savefile->Write(&endColor, sizeof(endColor));
-
- }
- void SSDPoints::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) {
- SSDEntity::ReadFromSaveGame(savefile, _game);
- savefile->Read(&length, sizeof(length));
- savefile->Read(&distance, sizeof(distance));
- savefile->Read(&beginTime, sizeof(beginTime));
- savefile->Read(&endTime, sizeof(endTime));
- savefile->Read(&beginPosition, sizeof(beginPosition));
- savefile->Read(&endPosition, sizeof(endPosition));
- savefile->Read(&beginColor, sizeof(beginColor));
- savefile->Read(&endColor, sizeof(endColor));
- }
- void SSDPoints::Init(idGameSSDWindow* _game, SSDEntity* _ent, int _points, int _length, int _distance, const idVec4& color) {
- EntityInit();
-
- SetGame(_game);
- length = _length;
- distance = _distance;
- beginTime = game->ssdTime;
- endTime = beginTime + length;
- textScale = 0.4f;
- text = va("%d", _points);
- float width = 0;
- for(int i = 0; i < text.Length(); i++) {
- width += dc->CharWidth(text[i], textScale);
- }
- size.Set(0,0);
- //Set the start position at the top of the passed in entity
- position = WorldToScreen(_ent->position);
- position = ScreenToWorld(position);
- position.z = 0;
- position.x -= (width/2.0f);
- beginPosition = position;
- endPosition = beginPosition;
- endPosition.y += _distance;
- //beginColor.Set(0,1,0,1);
- endColor.Set(1,1,1,0);
-
- beginColor = color;
- beginColor.w = 1;
- noPlayerDamage = true;
- noHit = true;
- }
- void SSDPoints::EntityUpdate() {
- float t = (float)(currentTime - beginTime)/(float)length;
- //Move up from the start position
- position.Lerp(beginPosition, endPosition, t);
- //Interpolate the color
- foreColor.Lerp(beginColor, endColor, t);
- if(currentTime > endTime) {
- destroyed = true;
- }
- }
- SSDPoints* SSDPoints::GetNewPoints(idGameSSDWindow* _game, SSDEntity* _ent, int _points, int _length, int _distance, const idVec4& color) {
- for(int i = 0; i < MAX_POINTS; i++) {
- if(!pointsPool[i].inUse) {
- pointsPool[i].Init(_game, _ent, _points, _length, _distance, color);
- pointsPool[i].inUse = true;
- return &pointsPool[i];
- }
- }
- return NULL;
- }
- SSDPoints* SSDPoints::GetSpecificPoints(int id) {
- return &pointsPool[id];
- }
- void SSDPoints::WritePoints(idFile* savefile) {
- int count = 0;
- for(int i = 0; i < MAX_POINTS; i++) {
- if(pointsPool[i].inUse) {
- count++;
- }
- }
- savefile->Write(&count, sizeof(count));
- for(int i = 0; i < MAX_POINTS; i++) {
- if(pointsPool[i].inUse) {
- savefile->Write(&(pointsPool[i].id), sizeof(pointsPool[i].id));
- pointsPool[i].WriteToSaveGame(savefile);
- }
- }
- }
- void SSDPoints::ReadPoints(idFile* savefile, idGameSSDWindow* _game) {
- int count;
- savefile->Read(&count, sizeof(count));
- for(int i = 0; i < count; i++) {
- int id;
- savefile->Read(&id, sizeof(id));
- SSDPoints* ent = GetSpecificPoints(id);
- ent->ReadFromSaveGame(savefile, _game);
- }
- }
- /*
- *****************************************************************************
- * SSDProjectile
- ****************************************************************************
- */
- SSDProjectile SSDProjectile::projectilePool[MAX_PROJECTILES];
- #define PROJECTILE_MATERIAL "game/SSD/fball"
- SSDProjectile::SSDProjectile() {
- type = SSD_ENTITY_PROJECTILE;
- }
- SSDProjectile::~SSDProjectile() {
- }
- void SSDProjectile::WriteToSaveGame( idFile *savefile ) {
- SSDEntity::WriteToSaveGame(savefile);
- savefile->Write(&dir, sizeof(dir));
- savefile->Write(&speed, sizeof(speed));
- savefile->Write(&beginTime, sizeof(beginTime));
- savefile->Write(&endTime, sizeof(endTime));
- savefile->Write(&endPosition, sizeof(endPosition));
- }
- void SSDProjectile::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) {
- SSDEntity::ReadFromSaveGame(savefile, _game);
- savefile->Read(&dir, sizeof(dir));
- savefile->Read(&speed, sizeof(speed));
- savefile->Read(&beginTime, sizeof(beginTime));
- savefile->Read(&endTime, sizeof(endTime));
- savefile->Read(&endPosition, sizeof(endPosition));
- }
- void SSDProjectile::Init(idGameSSDWindow* _game, const idVec3& _beginPosition, const idVec3& _endPosition, float _speed, float _size) {
-
- EntityInit();
- SetGame(_game);
- SetMaterial(PROJECTILE_MATERIAL);
- size.Set(_size,_size);
- position = _beginPosition;
- endPosition = _endPosition;
- dir = _endPosition - position;
- dir.Normalize();
- //speed.Zero();
- speed.x = speed.y = speed.z = _speed;
- noHit = true;
- }
- void SSDProjectile::EntityUpdate() {
- SSDEntity::EntityUpdate();
- //Move forward based on speed (units per second)
- idVec3 moved = dir*((float)elapsed/1000.0f)*speed.z;
- position += moved;
- if(position.z > endPosition.z) {
- //We have reached our position
- destroyed = true;
- }
- }
- SSDProjectile* SSDProjectile::GetNewProjectile(idGameSSDWindow* _game, const idVec3& _beginPosition, const idVec3& _endPosition, float _speed, float _size) {
- for(int i = 0; i < MAX_PROJECTILES; i++) {
- if(!projectilePool[i].inUse) {
- projectilePool[i].Init(_game, _beginPosition, _endPosition, _speed, _size);
- projectilePool[i].inUse = true;
- return &projectilePool[i];
- }
- }
- return NULL;
- }
- SSDProjectile* SSDProjectile::GetSpecificProjectile(int id) {
- return &projectilePool[id];
- }
- void SSDProjectile::WriteProjectiles(idFile* savefile) {
- int count = 0;
- for(int i = 0; i < MAX_PROJECTILES; i++) {
- if(projectilePool[i].inUse) {
- count++;
- }
- }
- savefile->Write(&count, sizeof(count));
- for(int i = 0; i < MAX_PROJECTILES; i++) {
- if(projectilePool[i].inUse) {
- savefile->Write(&(projectilePool[i].id), sizeof(projectilePool[i].id));
- projectilePool[i].WriteToSaveGame(savefile);
- }
- }
- }
- void SSDProjectile::ReadProjectiles(idFile* savefile, idGameSSDWindow* _game) {
- int count;
- savefile->Read(&count, sizeof(count));
- for(int i = 0; i < count; i++) {
- int id;
- savefile->Read(&id, sizeof(id));
- SSDProjectile* ent = GetSpecificProjectile(id);
- ent->ReadFromSaveGame(savefile, _game);
- }
- }
- /*
- *****************************************************************************
- * SSDPowerup
- ****************************************************************************
- */
- const char* powerupMaterials[][2] = {
- "game/SSD/powerupHealthClosed", "game/SSD/powerupHealthOpen",
- "game/SSD/powerupSuperBlasterClosed", "game/SSD/powerupSuperBlasterOpen",
- "game/SSD/powerupNukeClosed", "game/SSD/powerupNukeOpen",
- "game/SSD/powerupRescueClosed", "game/SSD/powerupRescueOpen",
- "game/SSD/powerupBonusPointsClosed", "game/SSD/powerupBonusPointsOpen",
- "game/SSD/powerupDamageClosed", "game/SSD/powerupDamageOpen",
- };
- #define POWERUP_MATERIAL_COUNT 6
- SSDPowerup SSDPowerup::powerupPool[MAX_POWERUPS];
- SSDPowerup::SSDPowerup() {
-
- }
- SSDPowerup::~SSDPowerup() {
- }
- void SSDPowerup::WriteToSaveGame( idFile *savefile ) {
- SSDMover::WriteToSaveGame(savefile);
- savefile->Write(&powerupState, sizeof(powerupState));
- savefile->Write(&powerupType, sizeof(powerupType));
- }
- void SSDPowerup::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) {
- SSDMover::ReadFromSaveGame(savefile, _game);
- savefile->Read(&powerupState, sizeof(powerupState));
- savefile->Read(&powerupType, sizeof(powerupType));
- }
- void SSDPowerup::OnHit(int key) {
- if(powerupState == POWERUP_STATE_CLOSED) {
- //Small explosion to indicate it is opened
- SSDExplosion* explosion = SSDExplosion::GetNewExplosion(game, position, size*2.0f, 300, SSDExplosion::EXPLOSION_NORMAL, this, false, true);
- game->entities.Append(explosion);
-
- powerupState = POWERUP_STATE_OPEN;
- SetMaterial(powerupMaterials[powerupType][powerupState]);
- } else {
- //Destory the powerup with a big explosion
- SSDExplosion* explosion = SSDExplosion::GetNewExplosion(game, position, size*2, 300, SSDExplosion::EXPLOSION_NORMAL, this);
- game->entities.Append(explosion);
- game->PlaySound("arcade_explode");
- noHit = true;
- noPlayerDamage = true;
- }
- }
- void SSDPowerup::OnStrikePlayer() {
-
- if(powerupState == POWERUP_STATE_OPEN) {
- //The powerup was open so activate it
- OnActivatePowerup();
- }
- //Just destroy the powerup
- destroyed = true;
- }
- void SSDPowerup::OnOpenPowerup() {
- }
- void SSDPowerup::OnActivatePowerup() {
- switch(powerupType) {
- case POWERUP_TYPE_HEALTH:
- {
- game->AddHealth(10);
- break;
- }
- case POWERUP_TYPE_SUPER_BLASTER:
- {
- game->OnSuperBlaster();
- break;
- }
- case POWERUP_TYPE_ASTEROID_NUKE:
- {
- game->OnNuke();
- break;
- }
- case POWERUP_TYPE_RESCUE_ALL:
- {
- game->OnRescueAll();
- break;
- }
- case POWERUP_TYPE_BONUS_POINTS:
- {
- int points = (game->random.RandomInt(5)+1) * 100;
- game->AddScore(this, points);
- break;
- }
- case POWERUP_TYPE_DAMAGE:
- {
- game->AddDamage(10);
- game->PlaySound("arcade_explode");
- break;
- }
- }
- }
- void SSDPowerup::Init(idGameSSDWindow* _game, float _speed, float _rotation) {
- EntityInit();
- MoverInit(idVec3(0,0, -_speed), _rotation);
- SetGame(_game);
- SetSize(idVec2(200,200));
- SetRadius(Max(size.x, size.y), 0.3f);
- type = SSD_ENTITY_POWERUP;
-
- idVec3 startPosition;
- startPosition.x = game->random.RandomInt(V_WIDTH)-(V_WIDTH/2.0f);
- startPosition.y = game->random.RandomInt(V_HEIGHT)-(V_HEIGHT/2.0f);
- startPosition.z = ENTITY_START_DIST;
- position = startPosition;
- //SetPosition(startPosition);
- powerupState = POWERUP_STATE_CLOSED;
- powerupType = game->random.RandomInt(POWERUP_TYPE_MAX+1);
- if(powerupType >= POWERUP_TYPE_MAX) {
- powerupType = 0;
- }
- /*OutputDebugString(va("Powerup: %d\n", powerupType));
- if(powerupType == 0) {
- int x = 0;
- }*/
- SetMaterial(powerupMaterials[powerupType][powerupState]);
- }
- SSDPowerup* SSDPowerup::GetNewPowerup(idGameSSDWindow* _game, float _speed, float _rotation) {
- for(int i = 0; i < MAX_POWERUPS; i++) {
- if(!powerupPool[i].inUse) {
- powerupPool[i].Init(_game, _speed, _rotation);
- powerupPool[i].inUse = true;
- return &powerupPool[i];
- }
- }
- return NULL;
- }
- SSDPowerup* SSDPowerup::GetSpecificPowerup(int id) {
- return &powerupPool[id];
- }
- void SSDPowerup::WritePowerups(idFile* savefile) {
- int count = 0;
- for(int i = 0; i < MAX_POWERUPS; i++) {
- if(powerupPool[i].inUse) {
- count++;
- }
- }
- savefile->Write(&count, sizeof(count));
- for(int i = 0; i < MAX_POWERUPS; i++) {
- if(powerupPool[i].inUse) {
- savefile->Write(&(powerupPool[i].id), sizeof(powerupPool[i].id));
- powerupPool[i].WriteToSaveGame(savefile);
- }
- }
- }
- void SSDPowerup::ReadPowerups(idFile* savefile, idGameSSDWindow* _game) {
- int count;
- savefile->Read(&count, sizeof(count));
- for(int i = 0; i < count; i++) {
- int id;
- savefile->Read(&id, sizeof(id));
- SSDPowerup* ent = GetSpecificPowerup(id);
- ent->ReadFromSaveGame(savefile, _game);
- }
- }
- /*
- *****************************************************************************
- * idGameSSDWindow
- ****************************************************************************
- */
- idRandom idGameSSDWindow::random;
- idGameSSDWindow::idGameSSDWindow(idUserInterfaceLocal *g) : idWindow(g) {
- gui = g;
- CommonInit();
- }
- idGameSSDWindow::~idGameSSDWindow() {
- ResetGameStats();
- }
- void idGameSSDWindow::WriteToSaveGame( idFile *savefile ) {
- idWindow::WriteToSaveGame(savefile);
- savefile->Write(&ssdTime, sizeof(ssdTime));
- beginLevel.WriteToSaveGame(savefile);
- resetGame.WriteToSaveGame(savefile);
- continueGame.WriteToSaveGame(savefile);
- refreshGuiData.WriteToSaveGame(savefile);
- crosshair.WriteToSaveGame(savefile);
- savefile->Write(&screenBounds, sizeof(screenBounds));
- savefile->Write(&levelCount, sizeof(levelCount));
- for(int i = 0; i < levelCount; i++) {
- savefile->Write(&(levelData[i]), sizeof(SSDLevelData_t));
- savefile->Write(&(asteroidData[i]), sizeof(SSDAsteroidData_t));
- savefile->Write(&(astronautData[i]), sizeof(SSDAstronautData_t));
- savefile->Write(&(powerupData[i]), sizeof(SSDPowerupData_t));
- }
- savefile->Write(&weaponCount, sizeof(weaponCount));
- for(int i = 0; i < weaponCount; i++) {
- savefile->Write(&(weaponData[i]), sizeof(SSDWeaponData_t));
- }
- savefile->Write(&superBlasterTimeout, sizeof(superBlasterTimeout));
- savefile->Write(&gameStats, sizeof(SSDGameStats_t));
- //Write All Static Entities
- SSDAsteroid::WriteAsteroids(savefile);
- SSDAstronaut::WriteAstronauts(savefile);
- SSDExplosion::WriteExplosions(savefile);
- SSDPoints::WritePoints(savefile);
- SSDProjectile::WriteProjectiles(savefile);
- SSDPowerup::WritePowerups(savefile);
- int entCount = entities.Num();
- savefile->Write(&entCount, sizeof(entCount));
- for(int i = 0; i < entCount; i++) {
- savefile->Write(&(entities[i]->type), sizeof(entities[i]->type));
- savefile->Write(&(entities[i]->id), sizeof(entities[i]->id));
- }
- }
- void idGameSSDWindow::ReadFromSaveGame( idFile *savefile ) {
- idWindow::ReadFromSaveGame(savefile);
- savefile->Read(&ssdTime, sizeof(ssdTime));
- beginLevel.ReadFromSaveGame(savefile);
- resetGame.ReadFromSaveGame(savefile);
- continueGame.ReadFromSaveGame(savefile);
- refreshGuiData.ReadFromSaveGame(savefile);
- crosshair.ReadFromSaveGame(savefile);
- savefile->Read(&screenBounds, sizeof(screenBounds));
- savefile->Read(&levelCount, sizeof(levelCount));
- for(int i = 0; i < levelCount; i++) {
- SSDLevelData_t newLevel;
- savefile->Read(&newLevel, sizeof(SSDLevelData_t));
- levelData.Append(newLevel);
- SSDAsteroidData_t newAsteroid;
- savefile->Read(&newAsteroid, sizeof(SSDAsteroidData_t));
- asteroidData.Append(newAsteroid);
- SSDAstronautData_t newAstronaut;
- savefile->Read(&newAstronaut, sizeof(SSDAstronautData_t));
- astronautData.Append(newAstronaut);
-
- SSDPowerupData_t newPowerup;
- savefile->Read(&newPowerup, sizeof(SSDPowerupData_t));
- powerupData.Append(newPowerup);
- }
- savefile->Read(&weaponCount, sizeof(weaponCount));
- for(int i = 0; i < weaponCount; i++) {
- SSDWeaponData_t newWeapon;
- savefile->Read(&newWeapon, sizeof(SSDWeaponData_t));
- weaponData.Append(newWeapon);
- }
- savefile->Read(&superBlasterTimeout, sizeof(superBlasterTimeout));
-
- savefile->Read(&gameStats, sizeof(SSDGameStats_t));
- //Reset this because it is no longer valid
- gameStats.levelStats.targetEnt = NULL;
- SSDAsteroid::ReadAsteroids(savefile, this);
- SSDAstronaut::ReadAstronauts(savefile, this);
- SSDExplosion::ReadExplosions(savefile, this);
- SSDPoints::ReadPoints(savefile, this);
- SSDProjectile::ReadProjectiles(savefile, this);
- SSDPowerup::ReadPowerups(savefile, this);
- int entCount;
- savefile->Read(&entCount, sizeof(entCount));
- for(int i = 0; i < entCount; i++) {
- int type, id;
- savefile->Read(&type, sizeof(type));
- savefile->Read(&id, sizeof(id));
- SSDEntity* ent = GetSpecificEntity(type, id);
- if(ent) {
- entities.Append(ent);
- }
- }
- }
- const char *idGameSSDWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) {
-
- // need to call this to allow proper focus and capturing on embedded children
- const char *ret = idWindow::HandleEvent(event, updateVisuals);
- if(!gameStats.gameRunning) {
- return ret;
- }
- int key = event->evValue;
- if ( event->evType == SE_KEY ) {
- if ( !event->evValue2 ) {
- return ret;
- }
- if ( key == K_MOUSE1 || key == K_MOUSE2) {
- FireWeapon(key);
- } else {
- return ret;
- }
- }
- return ret;
- }
- idWinVar *idGameSSDWindow::GetWinVarByName (const char *_name, bool winLookup, drawWin_t** owner) {
- idWinVar *retVar = NULL;
- if (idStr::Icmp(_name, "beginLevel") == 0) {
- retVar = &beginLevel;
- }
- if (idStr::Icmp(_name, "resetGame") == 0) {
- retVar = &resetGame;
- }
- if (idStr::Icmp(_name, "continueGame") == 0) {
- retVar = &continueGame;
- }
- if (idStr::Icmp(_name, "refreshGuiData") == 0) {
- retVar = &refreshGuiData;
- }
-
- if(retVar) {
- return retVar;
- }
- return idWindow::GetWinVarByName(_name, winLookup, owner);
- }
- void idGameSSDWindow::Draw(int time, float x, float y) {
- //Update the game every frame before drawing
- UpdateGame();
- RefreshGuiData();
- if(gameStats.gameRunning) {
- ZOrderEntities();
- //Draw from back to front
- for(int i = entities.Num()-1; i >= 0; i--) {
- entities[i]->Draw();
- }
- //The last thing to draw is the crosshair
- idVec2 cursor;
- //GetCursor(cursor);
- cursor.x = gui->CursorX();
- cursor.y = gui->CursorY();
- crosshair.Draw(cursor);
- }
- }
- bool idGameSSDWindow::ParseInternalVar(const char *_name, idTokenParser *src) {
- if (idStr::Icmp(_name, "beginLevel") == 0) {
- beginLevel = src->ParseBool();
- return true;
- }
- if (idStr::Icmp(_name, "resetGame") == 0) {
- resetGame = src->ParseBool();
- return true;
- }
- if (idStr::Icmp(_name, "continueGame") == 0) {
- continueGame = src->ParseBool();
- return true;
- }
- if (idStr::Icmp(_name, "refreshGuiData") == 0) {
- refreshGuiData = src->ParseBool();
- return true;
- }
-
- if(idStr::Icmp(_name, "levelcount") == 0) {
- levelCount = src->ParseInt();
- for(int i = 0; i < levelCount; i++) {
- SSDLevelData_t newLevel;
- memset(&newLevel, 0, sizeof(SSDLevelData_t));
- levelData.Append(newLevel);
- SSDAsteroidData_t newAsteroid;
- memset(&newAsteroid, 0, sizeof(SSDAsteroidData_t));
- asteroidData.Append(newAsteroid);
- SSDAstronautData_t newAstronaut;
- memset(&newAstronaut, 0, sizeof(SSDAstronautData_t));
- astronautData.Append(newAstronaut);
- SSDPowerupData_t newPowerup;
- memset(&newPowerup, 0, sizeof(SSDPowerupData_t));
- powerupData.Append(newPowerup);
- }
- return true;
- }
- if(idStr::Icmp(_name, "weaponCount") == 0) {
- weaponCount = src->ParseInt();
- for(int i = 0; i < weaponCount; i++) {
- SSDWeaponData_t newWeapon;
- memset(&newWeapon, 0, sizeof(SSDWeaponData_t));
- weaponData.Append(newWeapon);
- }
- return true;
- }
- if(idStr::FindText(_name, "leveldata", false) >= 0) {
- idStr tempName = _name;
- int level = atoi(tempName.Right(2))-1;
- idStr levelData;
- ParseString(src, levelData);
- ParseLevelData(level, levelData);
- return true;
- }
- if(idStr::FindText(_name, "asteroiddata", false) >= 0) {
- idStr tempName = _name;
- int level = atoi(tempName.Right(2))-1;
- idStr asteroidData;
- ParseString(src, asteroidData);
- ParseAsteroidData(level, asteroidData);
- return true;
- }
- if(idStr::FindText(_name, "weapondata", false) >= 0) {
- idStr tempName = _name;
- int weapon = atoi(tempName.Right(2))-1;
- idStr weaponData;
- ParseString(src, weaponData);
- ParseWeaponData(weapon, weaponData);
- return true;
- }
- if(idStr::FindText(_name, "astronautdata", false) >= 0) {
- idStr tempName = _name;
- int level = atoi(tempName.Right(2))-1;
- idStr astronautData;
- ParseString(src, astronautData);
- ParseAstronautData(level, astronautData);
- return true;
- }
- if(idStr::FindText(_name, "powerupdata", false) >= 0) {
- idStr tempName = _name;
- int level = atoi(tempName.Right(2))-1;
- idStr powerupData;
- ParseString(src, powerupData);
- ParsePowerupData(level, powerupData);
- return true;
- }
- return idWindow::ParseInternalVar(_name, src);
- }
- void idGameSSDWindow::ParseLevelData(int level, const idStr& levelDataString) {
- idParser parser;
- idToken token;
- parser.LoadMemory(levelDataString.c_str(), levelDataString.Length(), "LevelData");
- levelData[level].spawnBuffer = parser.ParseFloat();
- levelData[level].needToWin = parser.ParseInt(); //Required Destroyed
- }
- void idGameSSDWindow::ParseAsteroidData(int level, const idStr& asteroidDataString) {
- idParser parser;
- idToken token;
- parser.LoadMemory(asteroidDataString.c_str(), asteroidDataString.Length(), "AsteroidData");
- asteroidData[level].speedMin = parser.ParseFloat(); //Speed Min
- asteroidData[level].speedMax = parser.ParseFloat(); //Speed Max
- asteroidData[level].sizeMin = parser.ParseFloat(); //Size Min
- asteroidData[level].sizeMax = parser.ParseFloat(); //Size Max
- asteroidData[level].rotateMin = parser.ParseFloat(); //Rotate Min (rotations per second)
- asteroidData[level].rotateMax = parser.ParseFloat(); //Rotate Max (rotations per second)
- asteroidData[level].spawnMin = parser.ParseInt(); //Spawn Min
- asteroidData[level].spawnMax = parser.ParseInt(); //Spawn Max
- asteroidData[level].asteroidHealth = parser.ParseInt(); //Health of the asteroid
- asteroidData[level].asteroidDamage = parser.ParseInt(); //Asteroid Damage
- asteroidData[level].asteroidPoints = parser.ParseInt(); //Points awarded for destruction
- }
- void idGameSSDWindow::ParsePowerupData(int level, const idStr& powerupDataString) {
-
- idParser parser;
- idToken token;
- parser.LoadMemory(powerupDataString.c_str(), powerupDataString.Length(), "PowerupData");
- powerupData[level].speedMin = parser.ParseFloat(); //Speed Min
- powerupData[level].speedMax = parser.ParseFloat(); //Speed Max
- powerupData[level].rotateMin = parser.ParseFloat(); //Rotate Min (rotations per second)
- powerupData[level].rotateMax = parser.ParseFloat(); //Rotate Max (rotations per second)
- powerupData[level].spawnMin = parser.ParseInt(); //Spawn Min
- powerupData[level].spawnMax = parser.ParseInt(); //Spawn Max
- }
- void idGameSSDWindow::ParseWeaponData(int weapon, const idStr& weaponDataString) {
- idParser parser;
- idToken token;
- parser.LoadMemory(weaponDataString.c_str(), weaponDataString.Length(), "WeaponData");
- weaponData[weapon].speed = parser.ParseFloat();
- weaponData[weapon].damage = parser.ParseFloat();
- weaponData[weapon].size = parser.ParseFloat();
- }
- void idGameSSDWindow::ParseAstronautData(int level, const idStr& astronautDataString) {
-
- idParser parser;
- idToken token;
- parser.LoadMemory(astronautDataString.c_str(), astronautDataString.Length(), "AstronautData");
- astronautData[level].speedMin = parser.ParseFloat(); //Speed Min
- astronautData[level].speedMax = parser.ParseFloat(); //Speed Max
- astronautData[level].rotateMin = parser.ParseFloat(); //Rotate Min (rotations per second)
- astronautData[level].rotateMax = parser.ParseFloat(); //Rotate Max (rotations per second)
- astronautData[level].spawnMin = parser.ParseInt(); //Spawn Min
- astronautData[level].spawnMax = parser.ParseInt(); //Spawn Max
- astronautData[level].health = parser.ParseInt(); //Health of the asteroid
- astronautData[level].points = parser.ParseInt(); //Asteroid Damage
- astronautData[level].penalty = parser.ParseInt(); //Points awarded for destruction
- }
- void idGameSSDWindow::CommonInit() {
- crosshair.InitCrosshairs();
- beginLevel = false;
- resetGame = false;
- continueGame = false;
- refreshGuiData = false;
- ssdTime = 0;
- levelCount = 0;
- weaponCount = 0;
- screenBounds = idBounds(idVec3(-320,-240,0), idVec3(320,240,0));
- superBlasterTimeout = 0;
- currentSound = 0;
- //Precahce all assets that are loaded dynamically
- declManager->FindMaterial(ASTEROID_MATERIAL);
- declManager->FindMaterial(ASTRONAUT_MATERIAL);
- for(int i = 0; i < EXPLOSION_MATERIAL_COUNT; i++) {
- declManager->FindMaterial(explosionMaterials[i]);
- }
- declManager->FindMaterial(PROJECTILE_MATERIAL);
- for(int i = 0; i < POWERUP_MATERIAL_COUNT; i++) {
- declManager->FindMaterial(powerupMaterials[i][0]);
- declManager->FindMaterial(powerupMaterials[i][1]);
- }
-
- // Precache sounds
- declManager->FindSound( "arcade_blaster" );
- declManager->FindSound( "arcade_capture" );
- declManager->FindSound( "arcade_explode" );
- ResetGameStats();
- }
- void idGameSSDWindow::ResetGameStats() {
- ResetEntities();
- //Reset the gamestats structure
- memset(&gameStats, 0, sizeof(gameStats));
- gameStats.health = 100;
- }
- void idGameSSDWindow::ResetLevelStats() {
-
- ResetEntities();
-
- //Reset the level statistics structure
- memset(&gameStats.levelStats, 0, sizeof(gameStats.levelStats));
-
- }
- void idGameSSDWindow::ResetEntities() {
- //Destroy all of the entities
- for(int i = 0; i < entities.Num(); i++) {
- entities[i]->DestroyEntity();
- }
- entities.Clear();
- }
- void idGameSSDWindow::StartGame() {
-
- gameStats.gameRunning = true;
- }
- void idGameSSDWindow::StopGame() {
-
- gameStats.gameRunning = false;
- }
- void idGameSSDWindow::GameOver() {
-
- StopGame();
- gui->HandleNamedEvent("gameOver");
- }
- void idGameSSDWindow::BeginLevel(int level) {
-
- ResetLevelStats();
- gameStats.currentLevel = level;
- StartGame();
- }
- /**
- * Continue game resets the players health
- */
- void idGameSSDWindow::ContinueGame() {
- gameStats.health = 100;
- StartGame();
- }
- void idGameSSDWindow::LevelComplete() {
-
- gameStats.prebonusscore = gameStats.score;
- // Add the bonuses
- int accuracy;
- if( !gameStats.levelStats.shotCount ) {
- accuracy = 0;
- } else {
- accuracy = (int)( ( (float)gameStats.levelStats.hitCount / (float)gameStats.levelStats.shotCount ) * 100.0f );
- }
- int accuracyPoints = Max( 0, accuracy - 50 ) * 20;
- gui->SetStateString("player_accuracy_score", va("%i", accuracyPoints));
- gameStats.score += accuracyPoints;
- int saveAccuracy;
- int totalAst = gameStats.levelStats.savedAstronauts + gameStats.levelStats.killedAstronauts;
- if( !totalAst ) {
- saveAccuracy = 0;
- } else {
- saveAccuracy = (int)( ( (float)gameStats.levelStats.savedAstronauts / (float)totalAst ) * 100.0f );
- }
- accuracyPoints = Max( 0, saveAccuracy - 50 ) * 20;
- gui->SetStateString("save_accuracy_score", va("%i", accuracyPoints));
- gameStats.score += accuracyPoints;
- StopSuperBlaster();
- gameStats.nextLevel++;
- if(gameStats.nextLevel >= levelCount) {
- //Have they beaten the game
- GameComplete();
- } else {
- //Make sure we don't go above the levelcount
- //min(gameStats.nextLevel, levelCount-1);
- StopGame();
- gui->HandleNamedEvent("levelComplete");
- }
- }
- void idGameSSDWindow::GameComplete() {
- StopGame();
- gui->HandleNamedEvent("gameComplete");
- }
- void idGameSSDWindow::UpdateGame() {
- //Check to see if and functions where called by the gui
- if(beginLevel == true) {
- beginLevel = false;
- BeginLevel(gameStats.nextLevel);
- }
- if(resetGame == true) {
- resetGame = false;
- ResetGameStats();
- }
- if(continueGame == true) {
- continueGame = false;
- ContinueGame();
- }
- if(refreshGuiData == true) {
- refreshGuiData = false;
- RefreshGuiData();
- }
- if(gameStats.gameRunning) {
- //We assume an upate every 16 milliseconds
- ssdTime += 16;
- if(superBlasterTimeout && ssdTime > superBlasterTimeout) {
- StopSuperBlaster();
- }
- //Find if we are targeting and enemy
- idVec2 cursor;
- //GetCursor(cursor);
- cursor.x = gui->CursorX();
- cursor.y = gui->CursorY();
- gameStats.levelStats.targetEnt = EntityHitTest(cursor);
- //Update from back to front
- for(int i = entities.Num()-1; i >= 0; i--) {
- entities[i]->Update();
- }
- CheckForHits();
- //Delete entities that need to be deleted
- for(int i = entities.Num()-1; i >= 0; i--) {
- if(entities[i]->destroyed) {
- SSDEntity* ent = entities[i];
- ent->DestroyEntity();
- entities.RemoveIndex(i);
- }
- }
- //Check if we can spawn an asteroid
- SpawnAsteroid();
- //Check if we should spawn an astronaut
- SpawnAstronaut();
- //Check if we should spawn an asteroid
- SpawnPowerup();
- }
- }
- void idGameSSDWindow::CheckForHits() {
-
- //See if the entity has gotten close enough
- for(int i = 0; i < entities.Num(); i++) {
- SSDEntity* ent = entities[i];
- if(ent->position.z <= Z_NEAR) {
- if(!ent->noPlayerDamage) {
- //Is the object still in the screen
- idVec3 entPos = ent->position;
- entPos.z = 0;
- idBounds entBounds(entPos);
- entBounds.ExpandSelf(ent->hitRadius);
- if(screenBounds.IntersectsBounds(entBounds)) {
- ent->OnStrikePlayer();
- //The entity hit the player figure out what is was and act appropriately
- if(ent->type == SSD_ENTITY_ASTEROID) {
- AsteroidStruckPlayer(static_cast<SSDAsteroid*>(ent));
- } else if(ent->type == SSD_ENTITY_ASTRONAUT) {
- AstronautStruckPlayer(static_cast<SSDAstronaut*>(ent));
- }
- } else {
- //Tag for removal later in the frame
- ent->destroyed = true;
- }
- }
- }
- }
- }
- void idGameSSDWindow::ZOrderEntities() {
- //Z-Order the entities
- //Using a simple sorting method
- for (int i = entities.Num()-1; i >= 0; i--) {
- bool flipped = false;
- for (int j = 0; j<i ; j++) {
- if (entities[j]->position.z > entities[j+1]->position.z) {
- SSDEntity* ent = entities[j];
- entities[j] = entities[j+1];
- entities[j+1] = ent;
- flipped = true;
- }
- }
- if (!flipped) {
- //Jump out because it is sorted
- break;
- }
- }
- }
- void idGameSSDWindow::SpawnAsteroid() {
- int currentTime = ssdTime;
- if(currentTime < gameStats.levelStats.nextAsteroidSpawnTime) {
- //Not time yet
- return;
- }
- //Lets spawn it
- idVec3 startPosition;
- float spawnBuffer = levelData[gameStats.currentLevel].spawnBuffer*2.0f;
- startPosition.x = random.RandomInt(V_WIDTH+spawnBuffer)-((V_WIDTH/2.0f)+spawnBuffer);
- startPosition.y = random.RandomInt(V_HEIGHT+spawnBuffer)-((V_HEIGHT/2.0f)+spawnBuffer);
- startPosition.z = ENTITY_START_DIST;
- float speed = random.RandomInt(asteroidData[gameStats.currentLevel].speedMax - asteroidData[gameStats.currentLevel].speedMin) + asteroidData[gameStats.currentLevel].speedMin;
- float size = random.RandomInt(asteroidData[gameStats.currentLevel].sizeMax - asteroidData[gameStats.currentLevel].sizeMin) + asteroidData[gameStats.currentLevel].sizeMin;
- float rotate = (random.RandomFloat() * (asteroidData[gameStats.currentLevel].rotateMax - asteroidData[gameStats.currentLevel].rotateMin)) + asteroidData[gameStats.currentLevel].rotateMin;
-
- SSDAsteroid* asteroid = SSDAsteroid::GetNewAsteroid(this, startPosition, idVec2(size, size), speed, rotate, asteroidData[gameStats.currentLevel].asteroidHealth);
- entities.Append(asteroid);
-
- gameStats.levelStats.nextAsteroidSpawnTime = currentTime + random.RandomInt(asteroidData[gameStats.currentLevel].spawnMax - asteroidData[gameStats.currentLevel].spawnMin) + asteroidData[gameStats.currentLevel].spawnMin;
- }
- void idGameSSDWindow::FireWeapon(int key) {
- idVec2 cursorWorld = GetCursorWorld();
- idVec2 cursor;
- //GetCursor(cursor);
- cursor.x = gui->CursorX();
- cursor.y = gui->CursorY();
- if(key == K_MOUSE1) {
-
- gameStats.levelStats.shotCount++;
-
- if(gameStats.levelStats.targetEnt) {
- //Aim the projectile from the bottom of the screen directly at the ent
- //SSDProjectile* newProj = new (TAG_OLD_UI) SSDProjectile(this, idVec3(320,0,0), gameStats.levelStats.targetEnt->position, weaponData[gameStats.currentWeapon].speed, weaponData[gameStats.currentWeapon].size);
- SSDProjectile* newProj = SSDProjectile::GetNewProjectile(this, idVec3(0,-180,0), gameStats.levelStats.targetEnt->position, weaponData[gameStats.currentWeapon].speed, weaponData[gameStats.currentWeapon].size);
- entities.Append(newProj);
- //newProj = SSDProjectile::GetNewProjectile(this, idVec3(-320,-0,0), gameStats.levelStats.targetEnt->position, weaponData[gameStats.currentWeapon].speed, weaponData[gameStats.currentWeapon].size);
- //entities.Append(newProj);
- //We hit something
- gameStats.levelStats.hitCount++;
- gameStats.levelStats.targetEnt->OnHit(key);
- if(gameStats.levelStats.targetEnt->type == SSD_ENTITY_ASTEROID) {
- HitAsteroid(static_cast<SSDAsteroid*>(gameStats.levelStats.targetEnt), key);
- } else if(gameStats.levelStats.targetEnt->type == SSD_ENTITY_ASTRONAUT) {
- HitAstronaut(static_cast<SSDAstronaut*>(gameStats.levelStats.targetEnt), key);
- }
- } else {
- ////Aim the projectile at the cursor position all the way to the far clipping
- //SSDProjectile* newProj = SSDProjectile::GetNewProjectile(this, idVec3(0,-180,0), idVec3(cursorWorld.x, cursorWorld.y, (Z_FAR-Z_NEAR)/2.0f), weaponData[gameStats.currentWeapon].speed, weaponData[gameStats.currentWeapon].size);
- //Aim the projectile so it crosses the cursor 1/4 of screen
- idVec3 vec = idVec3(cursorWorld.x, cursorWorld.y, (Z_FAR-Z_NEAR)/8.0f);
- vec *= 8;
- SSDProjectile* newProj = SSDProjectile::GetNewProjectile(this, idVec3(0,-180,0), vec, weaponData[gameStats.currentWeapon].speed, weaponData[gameStats.currentWeapon].size);
- entities.Append(newProj);
-
- }
- //Play the blaster sound
- PlaySound("arcade_blaster");
- } /*else if (key == K_MOUSE2) {
- if(gameStats.levelStats.targetEnt) {
- if(gameStats.levelStats.targetEnt->type == SSD_ENTITY_ASTRONAUT) {
- HitAstronaut(static_cast<SSDAstronaut*>(gameStats.levelStats.targetEnt), key);
- }
- }
- }*/
- }
- SSDEntity* idGameSSDWindow::EntityHitTest(const idVec2& pt) {
- for(int i = 0; i < entities.Num(); i++) {
- //Since we ZOrder the entities every frame we can stop at the first entity we hit.
- //ToDo: Make sure this assumption is true
- if(entities[i]->HitTest(pt)) {
- return entities[i];
- }
- }
- return NULL;
- }
- void idGameSSDWindow::HitAsteroid(SSDAsteroid* asteroid, int key) {
-
- asteroid->health -= weaponData[gameStats.currentWeapon].damage;
- if(asteroid->health <= 0) {
-
- //The asteroid has been destroyed
- SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, asteroid->position, asteroid->size*2, 300, SSDExplosion::EXPLOSION_NORMAL, asteroid);
- entities.Append(explosion);
- PlaySound("arcade_explode");
- AddScore(asteroid, asteroidData[gameStats.currentLevel].asteroidPoints);
- //Don't let the player hit it anymore because
- asteroid->noHit = true;
- gameStats.levelStats.destroyedAsteroids++;
- //if(gameStats.levelStats.destroyedAsteroids >= levelData[gameStats.currentLevel].needToWin) {
- // LevelComplete();
- //}
- } else {
- //This was a damage hit so create a real small quick explosion
- SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, asteroid->position, asteroid->size/2.0f, 200, SSDExplosion::EXPLOSION_NORMAL, asteroid, false, false);
- entities.Append(explosion);
- }
- }
- void idGameSSDWindow::AsteroidStruckPlayer(SSDAsteroid* asteroid) {
- asteroid->noPlayerDamage = true;
- asteroid->noHit = true;
-
- AddDamage(asteroidData[gameStats.currentLevel].asteroidDamage);
- SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, asteroid->position, asteroid->size*2, 300, SSDExplosion::EXPLOSION_NORMAL, asteroid);
- entities.Append(explosion);
- PlaySound("arcade_explode");
- }
- void idGameSSDWindow::AddScore(SSDEntity* ent, int points) {
- SSDPoints* pointsEnt;
-
- if(points > 0) {
- pointsEnt = SSDPoints::GetNewPoints(this, ent, points, 1000, 50, idVec4(0,1,0,1));
- } else {
- pointsEnt = SSDPoints::GetNewPoints(this, ent, points, 1000, 50, idVec4(1,0,0,1));
- }
- entities.Append(pointsEnt);
- gameStats.score += points;
- gui->SetStateString( "player_score", va("%i", gameStats.score ) );
- }
- void idGameSSDWindow::AddDamage(int damage) {
- gameStats.health -= damage;
- gui->SetStateString( "player_health", va("%i", gameStats.health ) );
- gui->HandleNamedEvent( "playerDamage" );
- if(gameStats.health <= 0) {
- //The player is dead
- GameOver();
- }
- }
- void idGameSSDWindow::AddHealth(int health) {
- gameStats.health += health;
- gameStats.health = Min( 100, gameStats.health );
- }
- void idGameSSDWindow::OnNuke() {
-
- gui->HandleNamedEvent("nuke");
- //Destory All Asteroids
- for(int i = 0 ; i < entities.Num(); i++) {
- if(entities[i]->type == SSD_ENTITY_ASTEROID) {
-
- //The asteroid has been destroyed
- SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, entities[i]->position, entities[i]->size*2, 300, SSDExplosion::EXPLOSION_NORMAL, entities[i]);
- entities.Append(explosion);
- AddScore(entities[i], asteroidData[gameStats.currentLevel].asteroidPoints);
- //Don't let the player hit it anymore because
- entities[i]->noHit = true;
- gameStats.levelStats.destroyedAsteroids++;
- }
- }
- PlaySound("arcade_explode");
-
- //Check to see if a nuke ends the level
- /*if(gameStats.levelStats.destroyedAsteroids >= levelData[gameStats.currentLevel].needToWin) {
- LevelComplete();
- }*/
- }
- void idGameSSDWindow::OnRescueAll() {
-
- gui->HandleNamedEvent("rescueAll");
- //Rescue All Astronauts
- for(int i = 0 ; i < entities.Num(); i++) {
- if(entities[i]->type == SSD_ENTITY_ASTRONAUT) {
- AstronautStruckPlayer((SSDAstronaut*)entities[i]);
- }
- }
- }
- void idGameSSDWindow::OnSuperBlaster() {
-
- StartSuperBlaster();
- }
- void idGameSSDWindow::RefreshGuiData() {
- gui->SetStateString("nextLevel", va("%i", gameStats.nextLevel+1));
- gui->SetStateString("currentLevel", va("%i", gameStats.currentLevel+1));
- float accuracy;
- if(!gameStats.levelStats.shotCount) {
- accuracy = 0;
- } else {
- accuracy = ((float)gameStats.levelStats.hitCount/(float)gameStats.levelStats.shotCount)*100.0f;
- }
- gui->SetStateString( "player_accuracy", va("%d%%", (int)accuracy));
- float saveAccuracy;
- int totalAst = gameStats.levelStats.savedAstronauts + gameStats.levelStats.killedAstronauts;
- if(!totalAst) {
- saveAccuracy = 0;
- } else {
- saveAccuracy = ((float)gameStats.levelStats.savedAstronauts/(float)totalAst)*100.0f;
- }
- gui->SetStateString( "save_accuracy", va("%d%%", (int)saveAccuracy));
- if(gameStats.levelStats.targetEnt) {
- int dist = (gameStats.levelStats.targetEnt->position.z/100.0f);
- dist *= 100;
- gui->SetStateString("target_info", va("%i meters", dist));
- } else {
- gui->SetStateString("target_info", "No Target");
- }
- gui->SetStateString( "player_health", va("%i", gameStats.health ) );
- gui->SetStateString( "player_score", va("%i", gameStats.score ) );
- gui->SetStateString( "player_prebonusscore", va("%i", gameStats.prebonusscore ) );
- gui->SetStateString( "level_complete", va("%i/%i", gameStats.levelStats.savedAstronauts, levelData[gameStats.currentLevel].needToWin ));
- if(superBlasterTimeout) {
- float timeRemaining = (superBlasterTimeout - ssdTime)/1000.0f;
- gui->SetStateString("super_blaster_time", va("%.2f", timeRemaining));
- }
- }
- idVec2 idGameSSDWindow::GetCursorWorld() {
-
- idVec2 cursor;
- //GetCursor(cursor);
- cursor.x = gui->CursorX();
- cursor.y = gui->CursorY();
- cursor.x = cursor.x - 0.5f * V_WIDTH;
- cursor.y = -(cursor.y - 0.5f * V_HEIGHT);
- return cursor;
- }
- void idGameSSDWindow::SpawnAstronaut() {
-
- int currentTime = ssdTime;
- if(currentTime < gameStats.levelStats.nextAstronautSpawnTime) {
- //Not time yet
- return;
- }
- //Lets spawn it
- idVec3 startPosition;
- startPosition.x = random.RandomInt(V_WIDTH)-(V_WIDTH/2.0f);
- startPosition.y = random.RandomInt(V_HEIGHT)-(V_HEIGHT/2.0f);
- startPosition.z = ENTITY_START_DIST;
- float speed = random.RandomInt(astronautData[gameStats.currentLevel].speedMax - astronautData[gameStats.currentLevel].speedMin) + astronautData[gameStats.currentLevel].speedMin;
- float rotate = (random.RandomFloat() * (astronautData[gameStats.currentLevel].rotateMax - astronautData[gameStats.currentLevel].rotateMin)) + astronautData[gameStats.currentLevel].rotateMin;
- SSDAstronaut* astronaut = SSDAstronaut::GetNewAstronaut(this, startPosition, speed, rotate, astronautData[gameStats.currentLevel].health);
- entities.Append(astronaut);
- gameStats.levelStats.nextAstronautSpawnTime = currentTime + random.RandomInt(astronautData[gameStats.currentLevel].spawnMax - astronautData[gameStats.currentLevel].spawnMin) + astronautData[gameStats.currentLevel].spawnMin;
- }
- void idGameSSDWindow::HitAstronaut(SSDAstronaut* astronaut, int key) {
- if(key == K_MOUSE1) {
- astronaut->health -= weaponData[gameStats.currentWeapon].damage;
- if(astronaut->health <= 0) {
- gameStats.levelStats.killedAstronauts++;
- //The astronaut has been destroyed
- SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, astronaut->position, astronaut->size*2, 300, SSDExplosion::EXPLOSION_NORMAL, astronaut);
- entities.Append(explosion);
- PlaySound("arcade_explode");
- //Add the penalty for killing the astronaut
- AddScore(astronaut, astronautData[gameStats.currentLevel].penalty);
- //Don't let the player hit it anymore
- astronaut->noHit = true;
- } else {
- //This was a damage hit so create a real small quick explosion
- SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, astronaut->position, astronaut->size/2.0f, 200, SSDExplosion::EXPLOSION_NORMAL, astronaut, false, false);
- entities.Append(explosion);
- }
- }
- }
- void idGameSSDWindow::AstronautStruckPlayer(SSDAstronaut* astronaut) {
- gameStats.levelStats.savedAstronauts++;
- astronaut->noPlayerDamage = true;
- astronaut->noHit = true;
- //We are saving an astronaut
- SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, astronaut->position, astronaut->size*2, 300, SSDExplosion::EXPLOSION_TELEPORT, astronaut);
- entities.Append(explosion);
- PlaySound("arcade_capture");
- //Give the player points for saving the astronaut
- AddScore(astronaut, astronautData[gameStats.currentLevel].points);
- if(gameStats.levelStats.savedAstronauts >= levelData[gameStats.currentLevel].needToWin) {
- LevelComplete();
- }
- }
- void idGameSSDWindow::SpawnPowerup() {
- int currentTime = ssdTime;
- if(currentTime < gameStats.levelStats.nextPowerupSpawnTime) {
- //Not time yet
- return;
- }
- float speed = random.RandomInt(powerupData[gameStats.currentLevel].speedMax - powerupData[gameStats.currentLevel].speedMin) + powerupData[gameStats.currentLevel].speedMin;
- float rotate = (random.RandomFloat() * (powerupData[gameStats.currentLevel].rotateMax - powerupData[gameStats.currentLevel].rotateMin)) + powerupData[gameStats.currentLevel].rotateMin;
- SSDPowerup* powerup = SSDPowerup::GetNewPowerup(this, speed, rotate);
- entities.Append(powerup);
- gameStats.levelStats.nextPowerupSpawnTime = currentTime + random.RandomInt(powerupData[gameStats.currentLevel].spawnMax - powerupData[gameStats.currentLevel].spawnMin) + powerupData[gameStats.currentLevel].spawnMin;
- }
- void idGameSSDWindow::StartSuperBlaster() {
-
- gui->HandleNamedEvent("startSuperBlaster");
- gameStats.currentWeapon = 1;
- superBlasterTimeout = ssdTime + 10000;
- }
- void idGameSSDWindow::StopSuperBlaster() {
- gui->HandleNamedEvent("stopSuperBlaster");
- gameStats.currentWeapon = 0;
- superBlasterTimeout = 0;
- }
- SSDEntity* idGameSSDWindow::GetSpecificEntity(int type, int id) {
- SSDEntity* ent = NULL;
- switch(type) {
- case SSD_ENTITY_ASTEROID:
- ent = SSDAsteroid::GetSpecificAsteroid(id);
- break;
- case SSD_ENTITY_ASTRONAUT:
- ent = SSDAstronaut::GetSpecificAstronaut(id);
- break;
- case SSD_ENTITY_EXPLOSION:
- ent = SSDExplosion::GetSpecificExplosion(id);
- break;
- case SSD_ENTITY_POINTS:
- ent = SSDPoints::GetSpecificPoints(id);
- break;
- case SSD_ENTITY_PROJECTILE:
- ent = SSDProjectile::GetSpecificProjectile(id);
- break;
- case SSD_ENTITY_POWERUP:
- ent = SSDPowerup::GetSpecificPowerup(id);
- break;
- }
- return ent;
- }
- #define MAX_SOUND_CHANNEL 8
- void idGameSSDWindow::PlaySound(const char* sound) {
- common->SW()->PlayShaderDirectly(sound, currentSound);
- currentSound++;
- if(currentSound >= MAX_SOUND_CHANNEL) {
- currentSound = 0;
- }
- }
|