123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715 |
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2016 RWS Inc, All Rights Reserved
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of version 2 of the GNU General Public License as published by
- // the Free Software Foundation
- //
- // This program 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 this program; if not, write to the Free Software Foundation, Inc.,
- // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- //
- // Warp.cpp
- // Project: Postal
- //
- // History:
- // 06/02/97 JMI Started.
- //
- // 06/06/97 JMI Priority was being set incorrectly (was adding the height
- // of this object to our Z, but since our hotspot is at our
- // bottom, our priority is simply our Z).
- //
- // 06/07/97 JMI Added WarpIn() and WarpInAnywhere() function bodies.
- // Also, added CreateWarpFromDude().
- //
- // 06/15/97 JMI Moved initialization of ms_stockpile into warp.cpp since
- // the stockpile is non aggregatable.
- //
- // 06/16/97 JMI Moved initialization of dude's original hitpoints such
- // that both warp types (ones where he is preallocated and
- // ones where he is allocated by the WarpIn called) set it.
- //
- // 06/17/97 JMI Converted all occurrences of rand() to GetRand() and
- // srand() to SeedRand().
- //
- // 06/29/97 JMI Converted EditRect(), EditRender(), and/or Render() to
- // use Map3Dto2D().
- //
- // 06/30/97 JMI Now maps the Z to 3D when loading fileversions previous to
- // 24.
- //
- // 07/09/97 JMI Now uses m_pRealm->Make2dResPath() to get the fullpath
- // for 2D image components.
- //
- // 07/19/97 JMI Added m_sRotY, the dude's initial rotation around the Y
- // axis. Also, now passes a GUI to CStockPile::UserEdit()
- // with some settings for us.
- //
- // 08/03/97 BRH Increased the starting hit points for the Dude if the
- // game difficulty is set to 11.
- //
- // 08/05/97 JMI Changed priority to use Z position rather than 2D
- // projected Y position.
- //
- // 08/08/97 JMI Upped GUI_ID_ROT_Y from 101 to 1001 so it wouldn't
- // conflict with the stockpile dialog.
- //
- // 08/10/97 JMI Now the warp places the dude via a call to
- // CDude::SetPosition().
- //
- // 08/14/97 JMI Switched references to g_GameSettings.m_sDifficulty to
- // m_pRealm->m_flags.sDifficulty.
- //
- // 09/30/97 JMI Filled in empty fields in ms_stockpile. Although it is
- // not necessary b/c of the implicit filescope zero init,
- // it just seems like a good idea. But they are still zero
- // (just using enums instead of 0s) so there should be no
- // synch problems with old versions.
- //
- // 12/01/97 BRH For multiplayer deathmatch, the warp sets the hit
- // points to WARP_DEATHMATCH_DEFAULT_HP which will be
- // set to an amount we determine to be more fun. Right
- // now, most levels are set to 500 hit points, but for
- // deathmatch, its too hard to kill each other.
- //
- //////////////////////////////////////////////////////////////////////////////
- //
- // This CThing-derived class will represent places and settings for dudes to
- // 'warp' in at/with.
- //
- //////////////////////////////////////////////////////////////////////////////
- #define WARP_CPP
- #include "RSPiX.h"
- #include "warp.h"
- #include "game.h"
- #include "reality.h"
- ////////////////////////////////////////////////////////////////////////////////
- // Macros/types/etc.
- ////////////////////////////////////////////////////////////////////////////////
- // This is for edit mode only.
- #define WARP_IMAGE_FILENAME "warp.bmp"
- #define GUI_FILENAME "res/editor/warp.gui"
- #define GUI_ID_ROT_Y 1001
- #define WARP_DEATHMATCH_DEFAULT_HP 100
- ////////////////////////////////////////////////////////////////////////////////
- // Variables/data
- ////////////////////////////////////////////////////////////////////////////////
- // The stockpile of ammo and health used by all CWarps.
- CStockPile CWarp::ms_stockpile =
- {
- // Use CDude defaults for stockpile.
- CDude::DefHitPoints,
- CDude::DefNumGrenades,
- CDude::DefNumFireBombs,
- CDude::DefNumMissiles,
- CDude::DefNumNapalms,
- CDude::DefNumBullets,
- CDude::DefNumShells,
- CDude::DefNumFuel,
- CDude::DefNumMines,
- CDude::DefNumHeatseekers,
- CDude::DefHasMachineGun,
- CDude::DefHasLauncher,
- CDude::DefHasShotgun,
- CDude::DefHasSprayCannon,
- CDude::DefHasFlamer,
- CDude::DefHasNapalmLauncher,
- CDude::DefHasDeathWadLauncher,
- CDude::DefHasDoubleBarrel,
- CDude::DefKevlarLayers,
-
- CDude::DefHasBackpack,
- };
- // Tracks file counter so we know when to load/save "common" data
- short CWarp::ms_sFileCount = 0;
- ////////////////////////////////////////////////////////////////////////////////
- // Load object (should call base class version!)
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::Load( // Returns 0 if successfull, non-zero otherwise
- RFile* pFile, // In: File to load from
- bool bEditMode, // In: True for edit mode, false otherwise
- short sFileCount, // In: File count (unique per file, never 0)
- ULONG ulFileVersion) // In: Version of file format to load.
- {
- short sResult = CThing::Load(pFile, bEditMode, sFileCount, ulFileVersion);
- if (sResult == 0)
- {
- // If statics have not yet been loaded . . .
- if (ms_sFileCount != sFileCount)
- {
- ms_sFileCount = sFileCount;
- ms_stockpile.Load(pFile, ulFileVersion);
- }
- switch (ulFileVersion)
- {
- default:
- case 32:
- pFile->Read(&m_sRotY);
- case 31:
- case 30:
- case 29:
- case 28:
- case 27:
- case 26:
- case 25:
- case 24:
- case 23:
- case 22:
- case 21:
- case 20:
- case 19:
- case 18:
- case 17:
- case 16:
- case 15:
- case 14:
- case 13:
- case 12:
- case 11:
- case 10:
- case 9:
- case 8:
- case 7:
- case 6:
- case 5:
- case 4:
- case 3:
- case 2:
- case 1:
- pFile->Read(&m_dX);
- pFile->Read(&m_dY);
- pFile->Read(&m_dZ);
- break;
- }
- // If the file version is earlier than the change to real 3D coords . . .
- if (ulFileVersion < 24)
- {
- // Convert to 3D.
- m_pRealm->MapY2DtoZ3D(
- m_dZ,
- &m_dZ);
- }
- // Make sure there were no file errors or format errors . . .
- if (!pFile->Error() && sResult == 0)
- {
- // If in edit mode . . .
- if (bEditMode == true)
- {
- // Get resources and initialize.
- sResult = Init();
- }
- }
- else
- {
- sResult = -1;
- TRACE("CWarp::Load(): Error reading from file!\n");
- }
- }
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Save object (should call base class version!)
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::Save( // Returns 0 if successfull, non-zero otherwise
- RFile* pFile, // In: File to save to
- short sFileCount) // In: File count (unique per file, never 0)
- {
- short sResult = CThing::Save(pFile, sFileCount);
- if (sResult == 0)
- {
- // Save common data just once per file (not with each object)
- if (ms_sFileCount != sFileCount)
- {
- ms_sFileCount = sFileCount;
- ms_stockpile.Save(pFile);
- }
- pFile->Write(&m_sRotY);
- pFile->Write(&m_dX);
- pFile->Write(&m_dY);
- pFile->Write(&m_dZ);
- // Make sure there were no file errors
- sResult = pFile->Error();
- }
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Startup object
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::Startup(void) // Returns 0 if successfull, non-zero otherwise
- {
- return 0;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Shutdown object
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::Shutdown(void) // Returns 0 if successfull, non-zero otherwise
- {
- return 0;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Suspend object
- ////////////////////////////////////////////////////////////////////////////////
- void CWarp::Suspend(void)
- {
- m_sSuspend++;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Resume object
- ////////////////////////////////////////////////////////////////////////////////
- void CWarp::Resume(void)
- {
- m_sSuspend--;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Update object
- ////////////////////////////////////////////////////////////////////////////////
- void CWarp::Update(void)
- {
- // Do schtuff.
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Render object
- ////////////////////////////////////////////////////////////////////////////////
- void CWarp::Render(void)
- {
- // Doesn't normally draw anything (see EditRender() for render during
- // edit mode).
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Called by editor to init new object at specified position
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::EditNew( // Returns 0 if successfull, non-zero otherwise
- short sX, // In: New x coord
- short sY, // In: New y coord
- short sZ) // In: New z coord
- {
- short sResult = 0;
-
- // Use specified position
- m_dX = (double)sX;
- m_dY = (double)sY;
- m_dZ = (double)sZ;
- sResult = Init();
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Called by editor to modify object
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::EditModify(void)
- {
- short sResult = 0;
- // Load our GUI.
- RGuiItem* pgui = RGuiItem::LoadInstantiate(FullPathVD(GUI_FILENAME));
- if (pgui)
- {
- // Set current Y axis rotation.
- RGuiItem* pguiRotY = pgui->GetItemFromId(GUI_ID_ROT_Y);
- if (pguiRotY)
- {
- pguiRotY->SetText("%d", m_sRotY);
- pguiRotY->Compose();
- }
- // Display stockpile's GUI with ours at the bottom.
- sResult = ms_stockpile.UserEdit(pgui);
- // If not cancelled . . .
- if (sResult == 0)
- {
- if (pguiRotY)
- {
- m_sRotY = pguiRotY->GetVal();
- }
- }
- // Destroy our GUI.
- delete pgui;
- }
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Called by editor to move object to specified position
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::EditMove( // Returns 0 if successfull, non-zero otherwise
- short sX, // In: New x coord
- short sY, // In: New y coord
- short sZ) // In: New z coord
- {
- m_dX = (double)sX;
- m_dY = (double)sY;
- m_dZ = (double)sZ;
- return 0;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Called by editor to get the clickable pos/area of an object in 2D.
- // (virtual (Overridden here)).
- ////////////////////////////////////////////////////////////////////////////////
- void CWarp::EditRect( // Returns nothiing.
- RRect* prc) // Out: Clickable pos/area of object.
- {
- Map3Dto2D(
- m_dX,
- m_dY,
- m_dZ,
- &(prc->sX),
- &(prc->sY) );
- prc->sW = 10; // Safety.
- prc->sH = 10; // Safety.
- if (m_sprite.m_pImage != NULL)
- {
- prc->sW = m_sprite.m_pImage->m_sWidth;
- prc->sH = m_sprite.m_pImage->m_sHeight;
- }
- prc->sX -= prc->sW / 2;
- prc->sY -= prc->sH;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Called by editor to get the hotspot of an object in 2D.
- // (virtual (Overridden here)).
- ////////////////////////////////////////////////////////////////////////////////
- void CWarp::EditHotSpot( // Returns nothiing.
- short* psX, // Out: X coord of 2D hotspot relative to
- // EditRect() pos.
- short* psY) // Out: Y coord of 2D hotspot relative to
- // EditRect() pos.
- {
- *psX = 0; // Safety.
- *psY = 0; // Safety.
- if (m_sprite.m_pImage != NULL)
- {
- *psX = m_sprite.m_pImage->m_sWidth / 2;
- *psY = m_sprite.m_pImage->m_sHeight;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Called by editor to update object
- ////////////////////////////////////////////////////////////////////////////////
- void CWarp::EditUpdate(void)
- {
- // The editor schtuff.
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Called by editor to render object
- ////////////////////////////////////////////////////////////////////////////////
- void CWarp::EditRender(void)
- {
- // Map from 3d to 2d coords
- Map3Dto2D(
- (short) m_dX,
- (short) m_dY,
- (short) m_dZ,
- &m_sprite.m_sX2,
- &m_sprite.m_sY2);
- // Priority is based on bottom edge of sprite on viewing plane.
- m_sprite.m_sPriority = m_dZ;
-
- // Center on image.
- m_sprite.m_sX2 -= m_sprite.m_pImage->m_sWidth / 2;
- m_sprite.m_sY2 -= m_sprite.m_pImage->m_sHeight;
- // Layer should be based on info we get from attribute map.
- m_sprite.m_sLayer = CRealm::GetLayerViaAttrib(m_pRealm->GetLayer((short) m_dX, (short) m_dZ));
- // Update sprite in scene
- m_pRealm->m_scene.UpdateSprite(&m_sprite);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Initialize object.
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::Init(void) // Returns 0 on success.
- {
- short sRes = GetResources();
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Get all required resources
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::GetResources(void) // Returns 0 if successfull, non-zero otherwise
- {
- short sResult = 0;
- // Safe to call even if no resource.
- FreeResources();
- sResult = rspGetResource(
- &g_resmgrGame,
- m_pRealm->Make2dResPath(WARP_IMAGE_FILENAME),
- &m_sprite.m_pImage);
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Free all resources
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::FreeResources(void) // Returns 0 if successfull, non-zero otherwise
- {
- short sResult = 0;
- if (m_sprite.m_pImage != NULL)
- {
- rspReleaseResource(&g_resmgrGame, &m_sprite.m_pImage);
- }
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Stocks, rejuvenates, and places a CDude. The dude can be passed to this
- // function or allocated by this function.
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::WarpIn( // Returns 0 on success.
- CDude** ppdude, // In: CDude to 'warp in', *ppdude = NULL to create one.
- // Out: Newly created CDude, if no CDude passed in.
- short sOptions) // In: Options for 'warp in'.
- {
- short sRes = 0; // Assume success.
- // If we are on difficulty 11, multiply the dude's hit points by 10 so that
- // the player can have some chance of playing.
- if (m_pRealm->m_flags.sDifficulty == 11)
- {
- ms_stockpile.m_sHitPoints *= 10;
- if (ms_stockpile.m_sHitPoints < 0)
- ms_stockpile.m_sHitPoints = 30000;
- }
- // If we are playing multiplayer deathmatch, then set the hitpoints to the
- // default deathmatch amount so that it is easier to kill each other
- // and thus more fun.
- if (m_pRealm->m_flags.bMultiplayer == true && m_pRealm->m_flags.bCoopMode == false)
- {
- ms_stockpile.m_sHitPoints = WARP_DEATHMATCH_DEFAULT_HP;
- }
- // If no dude passed . . .
- if (*ppdude == NULL)
- {
- sRes = ConstructWithID(CDudeID, m_pRealm, (CThing**)ppdude);
- if (sRes == 0)
- {
- // Copy stockpile to new CDude.
- (*ppdude)->m_stockpile.Copy(&ms_stockpile);
- // Initialize.
- sRes = (*ppdude)->Init();
- if (sRes == 0)
- {
- // Start up.
- sRes = (*ppdude)->Startup();
- if (sRes == 0)
- {
- // Successfully created and setup CDude.
- }
- else
- {
- TRACE("WarpIn(): (*ppdude)->Startup() failed.\n");
- }
- }
- else
- {
- TRACE("WarpIn(): (*ppdude)->Init() failed.\n");
- }
- }
- else
- {
- TRACE("WarpIn(): Construct() failed for CDude.\n");
- }
- }
- else
- {
- switch (sOptions & StockPileMask)
- {
- case CopyStockPile:
- // Copy stockpile to CDude.
- (*ppdude)->m_stockpile.Copy(&ms_stockpile);
- break;
- case UnionStockPile:
- // Union stockpile with CDude.
- (*ppdude)->m_stockpile.Union(&ms_stockpile);
- break;
- case AddStockPile:
- // Add stockpile to CDude.
- (*ppdude)->m_stockpile.Add(&ms_stockpile);
- break;
- }
- }
- // If successful so far . . .
- if (sRes == 0)
- {
- // Truncate to amount he can carry.
- (*ppdude)->m_stockpile.Truncate();
- if ((*ppdude)->m_stockpile.m_sHitPoints > 0)
- {
- // Base original hitpoints upon new settings.
- (*ppdude)->m_sOrigHitPoints = (*ppdude)->m_stockpile.m_sHitPoints;
- }
- // Place.
- (*ppdude)->SetPosition(m_dX, m_dY, m_dZ);
- // Orient.
- (*ppdude)->m_dRot = m_sRotY;
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Stocks, rejuvenates, and places a CDude at a random warp. The dude can
- // be passed to this function or allocated by this function.
- // (static)
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::WarpInAnywhere( // Returns 0 on success.
- CRealm* prealm, // In: Realm in which to choose CWarp.
- CDude** ppdude, // In: CDude to 'warp in', *ppdude = NULL to create one.
- // Out: Newly created CDude, if no CDude passed in.
- short sOptions) // In: Options for 'warp in'.
- {
- short sRes = 0; // Assume success.
- // Find a warp:
-
- short sNumWarps = prealm->m_asClassNumThings[CWarpID];
- if (sNumWarps > 0)
- {
- // Pick a random warp number.
- short sWarpNum = GetRand() % sNumWarps;
- // Find that warp.
- short i;
- CListNode<CThing>* pln = prealm->m_aclassHeads[CWarpID].m_pnNext;
- CListNode<CThing>* plnTail = &(prealm->m_aclassTails[CWarpID]);
- for (i = 0; i < sWarpNum && pln != plnTail; i++, pln = pln->m_pnNext)
- ;
-
- // If we found one . . .
- if (pln != plnTail)
- {
- ASSERT(pln->m_powner != NULL);
- // Do it.
- sRes = ((CWarp*)(pln->m_powner) )->WarpIn(ppdude, sOptions);
- }
- else
- {
- TRACE("WarpInAnywhere(): Failed to find chosen CWarp.\n");
- sRes = -2;
- }
- }
- else
- {
- TRACE("WarpInAnywhere(): Specified realm contains no CWarps.\n");
- sRes = -1;
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Creates a warp based on a dude's settings.
- // (static)
- ////////////////////////////////////////////////////////////////////////////////
- short CWarp::CreateWarpFromDude( // Returns 0 on success.
- CRealm* prealm, // In: Realm in which to choose CWarp.
- CDude* pdude, // In: Dude to create warp from.
- CWarp** ppwarp, // Out: New warp on success.
- bool bCopyStockPile) // In: true to copy stockpile, false otherwise.
- {
- short sRes = 0; // Assume success.
- // Create warp . . .
- if (ConstructWithID(CWarpID, prealm, (CThing**)ppwarp) == 0)
- {
- // Copy dude's position and orientation.
- (*ppwarp)->m_dX = pdude->m_dX;
- (*ppwarp)->m_dY = pdude->m_dY;
- (*ppwarp)->m_dZ = pdude->m_dZ;
- (*ppwarp)->m_sRotY = pdude->m_dRot;
- if (bCopyStockPile == true)
- {
- // Copy dude's stockpile.
- // Note that this is static member of warp so this only needs to be for
- // one, but the question is which one.
- (*ppwarp)->ms_stockpile.Copy( &(pdude->m_stockpile) );
- }
- }
- else
- {
- TRACE("CreateWarpFromDude(): ConstructWithID() failed.\n");
- sRes = -1;
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // EOF
- ////////////////////////////////////////////////////////////////////////////////
|