2015-05-19 21:54:34 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 1997, 2005 - 3D Realms Entertainment
|
|
|
|
|
|
|
|
This file is part of Shadow Warrior version 1.2
|
|
|
|
|
|
|
|
Shadow Warrior 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 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
Original Source: 1997 - Frank Maddin and Jim Norwood
|
|
|
|
Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
2019-10-09 16:09:05 +00:00
|
|
|
#include "ns.h"
|
|
|
|
|
2015-05-19 21:54:34 +00:00
|
|
|
#include "build.h"
|
|
|
|
|
2020-05-29 00:32:53 +00:00
|
|
|
#include "gamecontrol.h"
|
|
|
|
|
2015-05-19 21:54:34 +00:00
|
|
|
#include "names2.h"
|
|
|
|
#include "game.h"
|
|
|
|
#include "tags.h"
|
|
|
|
#include "break.h"
|
|
|
|
#include "sprite.h"
|
|
|
|
|
2019-10-09 16:09:05 +00:00
|
|
|
BEGIN_SW_NS
|
|
|
|
|
2021-12-24 13:12:21 +00:00
|
|
|
inline int16_t& QUAKE_Match(DSWActor* actor) { return SP_TAG2(actor); }
|
2021-12-24 14:21:44 +00:00
|
|
|
inline uint8_t& QUAKE_Zamt(DSWActor* actor) { return SP_TAG3(actor); }
|
2021-12-24 16:50:15 +00:00
|
|
|
#define QUAKE_Radius(actor) (SP_TAG4(actor))
|
|
|
|
#define QUAKE_Duration(actor) (SP_TAG5(actor))
|
|
|
|
#define QUAKE_WaitSecs(actor) (SP_TAG6(actor))
|
|
|
|
#define QUAKE_AngAmt(actor) (SP_TAG7(actor))
|
|
|
|
#define QUAKE_PosAmt(actor) (SP_TAG8(actor))
|
|
|
|
#define QUAKE_RandomTest(actor) (SP_TAG9(actor))
|
|
|
|
#define QUAKE_WaitTics(actor) (SP_TAG13(actor))
|
|
|
|
|
|
|
|
#define QUAKE_TestDontTaper(actor) (TEST_BOOL1(actor))
|
|
|
|
#define QUAKE_KillAfterQuake(actor) (TEST_BOOL2(actor))
|
2015-05-19 21:54:34 +00:00
|
|
|
// only for timed quakes
|
2021-12-24 16:50:15 +00:00
|
|
|
#define QUAKE_WaitForTrigger(actor) (TEST_BOOL3(actor))
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2022-09-05 18:58:30 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2021-12-24 16:50:15 +00:00
|
|
|
void CopyQuakeSpotToOn(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-12-30 15:51:56 +00:00
|
|
|
auto actorNew = insertActor(actor->sector(), STAT_QUAKE_SPOT);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-12-24 16:50:15 +00:00
|
|
|
actorNew->spr = actor->spr;
|
2022-10-04 17:06:49 +00:00
|
|
|
actorNew->clipdist = actor->clipdist;
|
2021-12-24 16:50:15 +00:00
|
|
|
actorNew->spr.cstat = 0;
|
|
|
|
actorNew->spr.extra = 0;
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-10-31 18:07:50 +00:00
|
|
|
change_actor_stat(actorNew, STAT_QUAKE_ON);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-12-24 16:50:15 +00:00
|
|
|
QUAKE_Duration(actorNew) *= 120;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-09-05 18:58:30 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2015-05-19 21:54:34 +00:00
|
|
|
void DoQuakeMatch(short match)
|
|
|
|
{
|
2021-11-02 17:55:08 +00:00
|
|
|
SWStatIterator it(STAT_QUAKE_SPOT);
|
|
|
|
while (auto actor = it.Next())
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-12-24 13:12:21 +00:00
|
|
|
if (QUAKE_Match(actor) == match)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-12-24 16:50:15 +00:00
|
|
|
if ((int16_t)QUAKE_WaitTics(actor) > 0)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
// its not waiting any more
|
2021-12-24 16:50:15 +00:00
|
|
|
RESET_BOOL3(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-12-24 16:50:15 +00:00
|
|
|
CopyQuakeSpotToOn(actor);
|
|
|
|
if (QUAKE_KillAfterQuake(actor))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-11-02 17:55:08 +00:00
|
|
|
KillActor(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-05 18:58:30 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2015-05-19 21:54:34 +00:00
|
|
|
void ProcessQuakeOn(void)
|
|
|
|
{
|
2021-11-02 17:55:08 +00:00
|
|
|
SWStatIterator it(STAT_QUAKE_ON);
|
|
|
|
while (auto actor = it.Next())
|
|
|
|
{
|
2015-05-19 21:54:34 +00:00
|
|
|
// get rid of quake when timer runs out
|
2021-12-24 16:50:15 +00:00
|
|
|
QUAKE_Duration(actor) -= synctics*4;
|
|
|
|
if (QUAKE_Duration(actor) < 0)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-11-02 17:55:08 +00:00
|
|
|
KillActor(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-05 18:58:30 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2015-05-19 21:54:34 +00:00
|
|
|
void ProcessQuakeSpot(void)
|
|
|
|
{
|
|
|
|
int rand_test;
|
|
|
|
|
|
|
|
// check timed quakes and random quakes
|
2021-10-31 17:10:59 +00:00
|
|
|
SWStatIterator it(STAT_QUAKE_SPOT);
|
|
|
|
while (auto actor = it.Next())
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
// not a timed quake
|
2021-12-24 16:50:15 +00:00
|
|
|
if (!QUAKE_WaitSecs(actor))
|
2015-05-19 21:54:34 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// don't process unless triggered
|
2021-12-24 16:50:15 +00:00
|
|
|
if (QUAKE_WaitForTrigger(actor))
|
2015-05-19 21:54:34 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// spawn a quake if time is up
|
2021-12-24 16:50:15 +00:00
|
|
|
SET_SP_TAG13(actor, (QUAKE_WaitTics(actor)-4*synctics));
|
|
|
|
if ((int16_t)QUAKE_WaitTics(actor) < 0)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
// reset timer - add in Duration of quake
|
2021-12-24 16:50:15 +00:00
|
|
|
SET_SP_TAG13(actor, (((QUAKE_WaitSecs(actor)*10) + QUAKE_Duration(actor)) * 120));
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
// spawn a quake if condition is met
|
2021-12-24 16:50:15 +00:00
|
|
|
rand_test = QUAKE_RandomTest(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
// wrong - all quakes need to happen at the same time on all computerssg
|
2021-12-25 15:30:22 +00:00
|
|
|
//if (!rand_test || (rand_test && StdRandomRange(128) < rand_test))
|
2021-09-20 06:59:54 +00:00
|
|
|
if (!rand_test || (rand_test && RandomRange(128) < rand_test))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-12-24 16:50:15 +00:00
|
|
|
CopyQuakeSpotToOn(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
// kill quake spot if needed
|
2021-12-24 16:50:15 +00:00
|
|
|
if (QUAKE_KillAfterQuake(actor))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-31 17:10:59 +00:00
|
|
|
DeleteNoSoundOwner(actor);
|
|
|
|
KillActor(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-05 18:58:30 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
2023-10-02 19:03:59 +00:00
|
|
|
void QuakeViewChange(DSWPlayer* pp, DVector3& tpos, DAngle& tang)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-12-24 16:37:27 +00:00
|
|
|
DSWActor* save_act = nullptr;
|
2022-09-07 11:38:15 +00:00
|
|
|
double save_dist = 62500;
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2022-09-07 11:38:15 +00:00
|
|
|
DVector3 tposdiff;
|
|
|
|
DAngle tangdiff;
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2020-05-29 00:32:53 +00:00
|
|
|
if (paused)
|
2015-05-19 21:54:34 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// find the closest quake - should be a strength value
|
2021-12-24 16:37:27 +00:00
|
|
|
DSWActor* actor = nullptr;
|
2021-11-02 17:55:08 +00:00
|
|
|
SWStatIterator it(STAT_QUAKE_ON);
|
2022-01-01 09:49:31 +00:00
|
|
|
while ((actor = it.Next()))
|
2021-11-02 17:55:08 +00:00
|
|
|
{
|
2023-09-30 10:51:34 +00:00
|
|
|
auto dist = (pp->GetActor()->getPosWithOffsetZ() - actor->spr.pos).Length();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
// shake whole level
|
2021-12-24 16:37:27 +00:00
|
|
|
if (QUAKE_TestDontTaper(actor))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
save_dist = dist;
|
2021-12-24 16:37:27 +00:00
|
|
|
save_act = actor;
|
2015-05-19 21:54:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dist < save_dist)
|
|
|
|
{
|
|
|
|
save_dist = dist;
|
2021-12-24 16:37:27 +00:00
|
|
|
save_act = actor;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-24 16:37:27 +00:00
|
|
|
if (!save_act)
|
2015-05-19 21:54:34 +00:00
|
|
|
return;
|
|
|
|
else
|
2021-12-24 16:37:27 +00:00
|
|
|
actor = save_act;
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2022-09-07 11:38:15 +00:00
|
|
|
double radius = QUAKE_Radius(actor) * 0.5;
|
2015-05-19 21:54:34 +00:00
|
|
|
if (save_dist > radius)
|
|
|
|
return;
|
|
|
|
|
2022-09-07 11:38:15 +00:00
|
|
|
tposdiff.Z = StdRandomRange(QUAKE_Zamt(actor)) - (QUAKE_Zamt(actor)/2);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2022-09-07 11:38:15 +00:00
|
|
|
int ang_amt = QUAKE_AngAmt(actor) * 4L;
|
2022-09-11 12:02:04 +00:00
|
|
|
tangdiff = mapangle(StdRandomRange(ang_amt) - (ang_amt/2));
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2022-09-07 11:38:15 +00:00
|
|
|
int pos_amt = QUAKE_PosAmt(actor) * 4L;
|
|
|
|
tposdiff.XY() = DVector2(StdRandomRange(pos_amt) - (pos_amt/2), StdRandomRange(pos_amt) - (pos_amt/2)) * (1. / 4.);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-12-24 16:37:27 +00:00
|
|
|
if (!QUAKE_TestDontTaper(actor))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
// scale values from epicenter
|
2022-09-07 11:38:15 +00:00
|
|
|
double dist_diff = radius - save_dist;
|
|
|
|
double scale_value = dist_diff / radius;
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2022-09-07 11:38:15 +00:00
|
|
|
tposdiff *= scale_value;
|
|
|
|
tangdiff *= scale_value;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
2022-09-07 11:38:15 +00:00
|
|
|
|
|
|
|
// Add difference values onto incoming references
|
|
|
|
tpos += tposdiff;
|
|
|
|
tang += tangdiff;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
2022-09-05 18:58:30 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2022-08-21 08:52:19 +00:00
|
|
|
void SpawnQuake(sectortype* sect, const DVector3& pos, int tics, int amt, int radius)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
|
2021-12-04 21:04:16 +00:00
|
|
|
auto actorNew = insertActor(sect, STAT_QUAKE_ON);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2022-08-21 08:52:19 +00:00
|
|
|
actorNew->spr.pos = pos;
|
2021-12-24 16:38:56 +00:00
|
|
|
actorNew->spr.cstat = 0;
|
|
|
|
actorNew->spr.extra = 0;
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-12-24 13:12:21 +00:00
|
|
|
QUAKE_Match(actorNew) = -1;
|
2021-12-24 14:21:44 +00:00
|
|
|
QUAKE_Zamt(actorNew) = uint8_t(amt);
|
2021-12-24 16:38:56 +00:00
|
|
|
QUAKE_Radius(actorNew) = radius/8;
|
|
|
|
QUAKE_Duration(actorNew) = tics;
|
|
|
|
QUAKE_AngAmt(actorNew) = 8;
|
|
|
|
QUAKE_PosAmt(actorNew) = 0;
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-11-02 22:08:59 +00:00
|
|
|
PlaySound(DIGI_ERUPTION, actorNew, v3df_follow|v3df_dontpan);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
2022-09-05 18:58:30 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2023-10-02 19:03:59 +00:00
|
|
|
bool SetQuake(DSWPlayer* pp, short tics, short amt)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2023-09-30 10:51:34 +00:00
|
|
|
SpawnQuake(pp->cursector, pp->GetActor()->getPosWithOffsetZ(), tics, amt, 30000);
|
2020-09-09 17:52:52 +00:00
|
|
|
return false;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
2021-12-11 02:49:58 +00:00
|
|
|
int SetExpQuake(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2022-08-21 08:52:19 +00:00
|
|
|
SpawnQuake(actor->sector(), actor->spr.pos, 40, 4, 20000); // !JIM! was 8, 40000
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-12-11 02:49:58 +00:00
|
|
|
int SetGunQuake(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2022-08-21 08:52:19 +00:00
|
|
|
SpawnQuake(actor->sector(), actor->spr.pos, 40, 8, 40000);
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-10-02 19:03:59 +00:00
|
|
|
int SetPlayerQuake(DSWPlayer* pp)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2023-09-30 10:51:34 +00:00
|
|
|
SpawnQuake(pp->cursector, pp->GetActor()->getPosWithOffsetZ(), 40, 8, 40000);
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-12-11 02:49:58 +00:00
|
|
|
int SetNuclearQuake(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2022-08-21 08:52:19 +00:00
|
|
|
SpawnQuake(actor->sector(), actor->spr.pos, 400, 8, 64000);
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-11-02 23:02:50 +00:00
|
|
|
int SetSumoQuake(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2022-08-21 08:52:19 +00:00
|
|
|
SpawnQuake(actor->sector(), actor->spr.pos, 120, 4, 20000);
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-11-02 23:02:50 +00:00
|
|
|
int SetSumoFartQuake(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2022-08-21 08:52:19 +00:00
|
|
|
SpawnQuake(actor->sector(), actor->spr.pos, 60, 4, 4000);
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-10-09 16:09:05 +00:00
|
|
|
END_SW_NS
|