2020-05-10 07:28:13 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 1996, 2003 - 3D Realms Entertainment
|
|
|
|
Copyright (C) 2000, 2003 - Matt Saettler (EDuke Enhancements)
|
2020-05-13 14:19:39 +00:00
|
|
|
Copyright (C) 2020 - Christoph Oelckers
|
2020-05-10 07:28:13 +00:00
|
|
|
|
|
|
|
This file is part of Enhanced Duke Nukem 3D version 1.5 - Atomic Edition
|
|
|
|
|
|
|
|
Duke Nukem 3D 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
|
|
Original Source: 1996 - Todd Replogle
|
|
|
|
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
|
|
|
|
|
|
|
|
EDuke enhancements integrated: 04/13/2003 - Matt Saettler
|
|
|
|
|
|
|
|
Note: EDuke source was in transition. Changes are in-progress in the
|
|
|
|
source as it is released.
|
|
|
|
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
2020-05-10 10:42:47 +00:00
|
|
|
#include "ns.h"
|
|
|
|
#include "global.h"
|
2020-06-24 19:21:02 +00:00
|
|
|
#include "sounds.h"
|
2020-07-03 21:56:14 +00:00
|
|
|
#include "names_d.h"
|
2020-07-07 15:56:20 +00:00
|
|
|
#include "mapinfo.h"
|
2020-10-21 17:14:41 +00:00
|
|
|
#include "dukeactor.h"
|
2020-12-01 11:52:49 +00:00
|
|
|
#include "secrets.h"
|
2020-05-10 07:28:13 +00:00
|
|
|
|
|
|
|
// PRIMITIVE
|
2020-05-10 10:42:47 +00:00
|
|
|
BEGIN_DUKE_NS
|
|
|
|
|
2022-12-09 16:07:15 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
bool checkaccessswitch_d(int snum, int switchpal, DDukeActor* act, walltype* wwal)
|
|
|
|
{
|
|
|
|
if (ps[snum].access_incs == 0)
|
|
|
|
{
|
|
|
|
if (switchpal == 0)
|
|
|
|
{
|
|
|
|
if ((ps[snum].got_access & 1))
|
|
|
|
ps[snum].access_incs = 1;
|
|
|
|
else FTA(70, &ps[snum]);
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (switchpal == 21)
|
|
|
|
{
|
|
|
|
if (ps[snum].got_access & 2)
|
|
|
|
ps[snum].access_incs = 1;
|
|
|
|
else FTA(71, &ps[snum]);
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (switchpal == 23)
|
|
|
|
{
|
|
|
|
if (ps[snum].got_access & 4)
|
|
|
|
ps[snum].access_incs = 1;
|
|
|
|
else FTA(72, &ps[snum]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ps[snum].access_incs == 1)
|
|
|
|
{
|
|
|
|
if (!act)
|
|
|
|
ps[snum].access_wall = wwal;
|
|
|
|
else
|
|
|
|
ps[snum].access_spritenum = act;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-10 18:59:38 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2021-11-18 17:51:19 +00:00
|
|
|
void activatebysector_d(sectortype* sect, DDukeActor* activator)
|
2020-05-10 18:59:38 +00:00
|
|
|
{
|
2021-11-07 13:55:28 +00:00
|
|
|
int didit = 0;
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2020-11-02 18:28:59 +00:00
|
|
|
DukeSectIterator it(sect);
|
|
|
|
while (auto act = it.Next())
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-11-20 11:43:24 +00:00
|
|
|
if (isactivator(act))
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-11-19 14:40:35 +00:00
|
|
|
operateactivators(act->spr.lotag, nullptr);
|
2020-05-12 11:43:24 +00:00
|
|
|
didit = 1;
|
|
|
|
// return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (didit == 0)
|
2020-11-02 18:28:59 +00:00
|
|
|
operatesectors(sect, activator);
|
2020-05-10 18:59:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2022-02-07 10:04:19 +00:00
|
|
|
void checkplayerhurt_d(player_struct* p, const Collision& coll)
|
2020-05-10 18:59:38 +00:00
|
|
|
{
|
2020-10-25 07:50:03 +00:00
|
|
|
if (coll.type == kHitSprite)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-11-15 09:17:23 +00:00
|
|
|
CallOnHurt(coll.actor(), p);
|
2020-05-12 11:43:24 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-10-25 07:50:03 +00:00
|
|
|
if (coll.type != kHitWall) return;
|
2021-11-26 12:41:15 +00:00
|
|
|
auto wal = coll.hitWall;
|
2020-05-12 11:43:24 +00:00
|
|
|
|
|
|
|
if (p->hurt_delay > 0) p->hurt_delay--;
|
2022-12-10 17:29:53 +00:00
|
|
|
else if (wal->cstat & (CSTAT_WALL_BLOCK | CSTAT_WALL_ALIGN_BOTTOM | CSTAT_WALL_MASKED | CSTAT_WALL_BLOCK_HITSCAN))
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-12-10 18:03:17 +00:00
|
|
|
int tf = tileflags(wal->overtexture);
|
2022-12-10 17:29:53 +00:00
|
|
|
if (tf & TFLAG_ANIMFORCEFIELD)
|
|
|
|
{
|
|
|
|
p->GetActor()->spr.extra -= 5;
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2022-12-10 17:29:53 +00:00
|
|
|
p->hurt_delay = 16;
|
|
|
|
SetPlayerPal(p, PalEntry(32, 32, 0, 0));
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2022-12-10 17:29:53 +00:00
|
|
|
p->vel.XY() = -p->GetActor()->spr.Angles.Yaw.ToVector() * 16;
|
|
|
|
S_PlayActorSound(DUKE_LONGTERM_PAIN, p->GetActor());
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2022-12-10 17:29:53 +00:00
|
|
|
checkhitwall(p->GetActor(), wal, p->GetActor()->getPosWithOffsetZ() + p->GetActor()->spr.Angles.Yaw.ToVector() * 2);
|
|
|
|
}
|
|
|
|
else if (tf & TFLAG_FORCEFIELD)
|
|
|
|
{
|
|
|
|
p->hurt_delay = 26;
|
|
|
|
checkhitwall(p->GetActor(), wal, p->GetActor()->getPosWithOffsetZ() + p->GetActor()->spr.Angles.Yaw.ToVector() * 2);
|
|
|
|
}
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
2020-05-10 18:59:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2022-01-20 07:31:08 +00:00
|
|
|
void checkhitdefault_d(DDukeActor* targ, DDukeActor* proj)
|
|
|
|
{
|
2022-11-24 06:42:17 +00:00
|
|
|
if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_WALL) && targ->spr.hitag == 0 && targ->spr.lotag == 0 && targ->spr.statnum == STAT_DEFAULT)
|
2022-01-20 07:31:08 +00:00
|
|
|
return;
|
|
|
|
|
2022-12-04 13:03:24 +00:00
|
|
|
if ((proj->spr.picnum == DTILE_FREEZEBLAST || proj->GetOwner() != targ) && targ->spr.statnum != STAT_PROJECTILE)
|
2022-01-20 07:31:08 +00:00
|
|
|
{
|
|
|
|
if (badguy(targ) == 1)
|
|
|
|
{
|
2022-12-04 13:03:24 +00:00
|
|
|
if (isWorldTour() && targ->spr.picnum == DTILE_FIREFLY && targ->spr.scale.X < 0.75)
|
2022-01-20 07:31:08 +00:00
|
|
|
return;
|
|
|
|
|
2022-12-04 13:03:24 +00:00
|
|
|
if (proj->spr.picnum == DTILE_RPG) proj->spr.extra <<= 1;
|
2022-01-20 07:31:08 +00:00
|
|
|
|
2022-12-04 13:03:24 +00:00
|
|
|
if ((targ->spr.picnum != DTILE_DRONE) && (targ->spr.picnum != DTILE_ROTATEGUN) && (targ->spr.picnum != DTILE_COMMANDER) && targ->spr.picnum != DTILE_GREENSLIME)
|
|
|
|
if (proj->spr.picnum != DTILE_FREEZEBLAST)
|
2022-11-29 16:36:01 +00:00
|
|
|
//if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL.
|
2022-01-20 07:31:08 +00:00
|
|
|
{
|
2022-12-04 13:03:24 +00:00
|
|
|
auto spawned = spawn(proj, DTILE_JIBS6);
|
2022-01-20 07:31:08 +00:00
|
|
|
if (spawned)
|
|
|
|
{
|
|
|
|
if (proj->spr.pal == 6)
|
|
|
|
spawned->spr.pal = 6;
|
|
|
|
spawned->spr.pos.Z += 4;
|
|
|
|
spawned->vel.X = 1;
|
|
|
|
spawned->spr.scale = DVector2(0.375, 0.375);
|
2022-11-25 12:13:50 +00:00
|
|
|
spawned->spr.Angles.Yaw = DAngle22_5 / 4 - randomAngle(22.5 / 2);
|
2022-01-20 07:31:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Owner = proj->GetOwner();
|
|
|
|
|
2022-12-04 13:03:24 +00:00
|
|
|
if (Owner && Owner->isPlayer() && targ->spr.picnum != DTILE_ROTATEGUN && targ->spr.picnum != DTILE_DRONE)
|
2022-01-20 07:31:08 +00:00
|
|
|
if (ps[Owner->PlayerIndex()].curr_weapon == SHOTGUN_WEAPON)
|
|
|
|
{
|
2022-12-20 21:25:48 +00:00
|
|
|
fi.shoot(targ, -1, PClass::FindActor(NAME_DukeBloodSplat3));
|
|
|
|
fi.shoot(targ, -1, PClass::FindActor(NAME_DukeBloodSplat1));
|
|
|
|
fi.shoot(targ, -1, PClass::FindActor(NAME_DukeBloodSplat2));
|
|
|
|
fi.shoot(targ, -1, PClass::FindActor(NAME_DukeBloodSplat4));
|
2022-01-20 07:31:08 +00:00
|
|
|
}
|
|
|
|
|
2022-12-20 21:25:48 +00:00
|
|
|
if (!(targ->flags2 & SFLAG2_NODAMAGEPUSH)) // RR does not have this.
|
2022-01-20 07:31:08 +00:00
|
|
|
{
|
|
|
|
if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == 0)
|
2022-11-25 12:13:50 +00:00
|
|
|
targ->spr.Angles.Yaw = proj->spr.Angles.Yaw + DAngle180;
|
2022-01-20 07:31:08 +00:00
|
|
|
|
|
|
|
targ->vel.X = -proj->spr.extra * 0.25;
|
|
|
|
auto sp = targ->sector();
|
|
|
|
pushmove(targ->spr.pos, &sp, 8, 4, 4, CLIPMASK0);
|
|
|
|
if (sp != targ->sector() && sp != nullptr)
|
|
|
|
ChangeActorSect(targ, sp);
|
|
|
|
}
|
|
|
|
|
2022-11-28 09:32:55 +00:00
|
|
|
if (targ->spr.statnum == STAT_ZOMBIEACTOR)
|
2022-01-20 07:31:08 +00:00
|
|
|
{
|
2022-11-28 09:32:55 +00:00
|
|
|
ChangeActorStat(targ, STAT_ACTOR);
|
2022-01-20 07:31:08 +00:00
|
|
|
targ->timetosleep = SLEEPTIME;
|
|
|
|
}
|
2022-12-04 13:03:24 +00:00
|
|
|
if ((targ->spr.scale.X < 0.375 || targ->spr.picnum == DTILE_SHARK) && proj->spr.picnum == DTILE_SHRINKSPARK) return;
|
2022-01-20 07:31:08 +00:00
|
|
|
}
|
|
|
|
|
2022-11-24 06:42:17 +00:00
|
|
|
if (targ->spr.statnum != STAT_ZOMBIEACTOR)
|
2022-01-20 07:31:08 +00:00
|
|
|
{
|
2022-12-20 21:25:48 +00:00
|
|
|
if ((proj->flags2 & SFLAG2_FREEZEDAMAGE) && ((targ->isPlayer() && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ)))
|
2022-01-20 07:31:08 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
int hitpic = proj->spr.picnum;
|
|
|
|
auto Owner = proj->GetOwner();
|
2022-11-26 13:48:51 +00:00
|
|
|
if (Owner && Owner->isPlayer())
|
2022-01-20 07:31:08 +00:00
|
|
|
{
|
2022-11-26 13:48:51 +00:00
|
|
|
if (targ->isPlayer() && ud.coop != 0 && ud.ffire == 0)
|
2022-01-20 07:31:08 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
auto tOwner = targ->GetOwner();
|
2022-12-04 13:03:24 +00:00
|
|
|
if (isWorldTour() && hitpic == DTILE_FIREBALL && tOwner && tOwner->spr.picnum != DTILE_FIREBALL)
|
|
|
|
hitpic = DTILE_FLAMETHROWERFLAME;
|
2022-01-20 07:31:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
targ->attackertype = hitpic;
|
|
|
|
targ->hitextra += proj->spr.extra;
|
2022-11-25 12:13:50 +00:00
|
|
|
targ->hitang = proj->spr.Angles.Yaw;
|
2022-01-20 07:31:08 +00:00
|
|
|
targ->SetHitOwner(Owner);
|
|
|
|
}
|
|
|
|
|
2022-11-24 06:42:17 +00:00
|
|
|
if (targ->spr.statnum == STAT_PLAYER)
|
2022-01-20 07:31:08 +00:00
|
|
|
{
|
|
|
|
auto p = targ->spr.yint;
|
|
|
|
if (ps[p].newOwner != nullptr)
|
|
|
|
{
|
|
|
|
ps[p].newOwner = nullptr;
|
2022-11-29 10:12:36 +00:00
|
|
|
ps[p].GetActor()->restoreloc();
|
2022-01-20 07:31:08 +00:00
|
|
|
|
2022-11-24 02:20:17 +00:00
|
|
|
updatesector(ps[p].GetActor()->getPosWithOffsetZ(), &ps[p].cursector);
|
2022-01-20 07:31:08 +00:00
|
|
|
|
|
|
|
DukeStatIterator it(STAT_ACTOR);
|
|
|
|
while (auto itActor = it.Next())
|
|
|
|
{
|
2022-12-20 21:25:48 +00:00
|
|
|
if (itActor->flags2 & SFLAG2_CAMERA) itActor->spr.yint = 0;
|
2022-01-20 07:31:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-04 13:03:24 +00:00
|
|
|
if (targ->spr.scale.X < 0.375 && proj->spr.picnum == DTILE_SHRINKSPARK)
|
2022-01-20 07:31:08 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
auto hitowner = targ->GetHitOwner();
|
2022-11-26 13:48:51 +00:00
|
|
|
if (!hitowner || !hitowner->isPlayer())
|
2022-01-20 07:31:08 +00:00
|
|
|
if (ud.player_skill >= 3)
|
|
|
|
proj->spr.extra += (proj->spr.extra >> 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-24 05:08:40 +00:00
|
|
|
void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj)
|
2020-05-10 18:59:38 +00:00
|
|
|
{
|
2022-01-17 23:30:43 +00:00
|
|
|
if (targ->GetClass() != RUNTIME_CLASS(DDukeActor))
|
|
|
|
{
|
|
|
|
CallOnHit(targ, proj);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-12-14 18:37:25 +00:00
|
|
|
if (targ->IsKindOf(NAME_DukePlayerOnWater))
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2020-10-24 04:28:41 +00:00
|
|
|
targ = targ->GetOwner();
|
2022-12-02 23:42:42 +00:00
|
|
|
if (!targ) return;
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
2022-12-02 23:42:42 +00:00
|
|
|
checkhitdefault_d(targ, proj);
|
2020-05-10 18:59:38 +00:00
|
|
|
}
|
|
|
|
|
2021-11-17 23:16:53 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// taken out of checksectors to eliminate some gotos.
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2022-01-21 00:04:08 +00:00
|
|
|
void clearcameras(player_struct* p)
|
2021-11-17 23:16:53 +00:00
|
|
|
{
|
2022-11-20 08:03:27 +00:00
|
|
|
p->GetActor()->restorepos();
|
2022-01-21 00:04:08 +00:00
|
|
|
p->newOwner = nullptr;
|
2021-11-17 23:16:53 +00:00
|
|
|
|
2022-11-24 02:20:17 +00:00
|
|
|
updatesector(p->GetActor()->getPosWithOffsetZ(), &p->cursector);
|
2021-11-17 23:16:53 +00:00
|
|
|
|
2022-01-21 00:04:08 +00:00
|
|
|
DukeStatIterator it(STAT_ACTOR);
|
|
|
|
while (auto act = it.Next())
|
|
|
|
{
|
2022-12-20 21:25:48 +00:00
|
|
|
if ((act->flags2 & SFLAG2_CAMERA)) act->spr.yint = 0;
|
2021-11-17 23:16:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-10 20:20:49 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void checksectors_d(int snum)
|
|
|
|
{
|
2022-09-13 22:11:16 +00:00
|
|
|
int i = -1;
|
2022-02-07 10:04:19 +00:00
|
|
|
player_struct* p;
|
2021-11-17 23:04:36 +00:00
|
|
|
walltype* hitscanwall;
|
2021-11-26 17:59:28 +00:00
|
|
|
HitInfo near;
|
2020-05-12 11:43:24 +00:00
|
|
|
|
|
|
|
p = &ps[snum];
|
2020-11-02 19:23:30 +00:00
|
|
|
auto pact = p->GetActor();
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2021-11-19 07:58:31 +00:00
|
|
|
if (!p->insector()) return;
|
|
|
|
|
2021-11-21 07:56:39 +00:00
|
|
|
switch (p->cursector->lotag)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
case 32767:
|
2021-11-21 07:56:39 +00:00
|
|
|
p->cursector->lotag = 0;
|
2020-05-12 11:43:24 +00:00
|
|
|
FTA(9, p);
|
|
|
|
p->secret_rooms++;
|
2022-11-15 11:03:44 +00:00
|
|
|
SECRET_Trigger(sectindex(p->cursector));
|
2020-05-12 11:43:24 +00:00
|
|
|
return;
|
|
|
|
case -1:
|
2021-11-21 07:56:39 +00:00
|
|
|
p->cursector->lotag = 0;
|
2020-07-07 15:56:20 +00:00
|
|
|
setnextmap(false);
|
2020-05-12 11:43:24 +00:00
|
|
|
return;
|
|
|
|
case -2:
|
2021-11-21 07:56:39 +00:00
|
|
|
p->cursector->lotag = 0;
|
2020-05-12 11:43:24 +00:00
|
|
|
p->timebeforeexit = 26 * 8;
|
2021-11-21 07:56:39 +00:00
|
|
|
p->customexitsound = p->cursector->hitag;
|
2020-05-12 11:43:24 +00:00
|
|
|
return;
|
|
|
|
default:
|
2021-11-21 07:56:39 +00:00
|
|
|
if (p->cursector->lotag >= 10000 && p->cursector->lotag < 16383)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
|
|
|
if (snum == screenpeek || ud.coop == 1)
|
2021-11-21 07:56:39 +00:00
|
|
|
S_PlayActorSound(p->cursector->lotag - 10000, pact);
|
|
|
|
p->cursector->lotag = 0;
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//After this point the the player effects the map with space
|
|
|
|
|
2021-12-21 17:19:45 +00:00
|
|
|
if (chatmodeon || p->GetActor()->spr.extra <= 0) return;
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2020-08-28 20:51:05 +00:00
|
|
|
if (ud.cashman && PlayerInput(snum, SB_OPEN))
|
2020-11-02 18:53:04 +00:00
|
|
|
fi.lotsofmoney(p->GetActor(), 2);
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2020-11-02 23:20:51 +00:00
|
|
|
if (p->newOwner != nullptr)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-11-19 17:26:17 +00:00
|
|
|
if (abs(PlayerInputSideVel(snum)) > 0.75 || abs(PlayerInputForwardVel(snum)) > 0.75)
|
|
|
|
{
|
|
|
|
clearcameras(p);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (PlayerInput(snum, SB_ESCAPE))
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-01-21 00:04:08 +00:00
|
|
|
clearcameras(p);
|
2021-11-17 23:16:53 +00:00
|
|
|
return;
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-29 11:32:14 +00:00
|
|
|
if (!(PlayerInput(snum, SB_OPEN)))
|
2020-05-12 11:43:24 +00:00
|
|
|
p->toggle_key_flag = 0;
|
|
|
|
|
|
|
|
else if (!p->toggle_key_flag)
|
|
|
|
{
|
2021-11-26 17:59:28 +00:00
|
|
|
near.hitActor = nullptr;
|
2020-05-12 11:43:24 +00:00
|
|
|
p->toggle_key_flag = 1;
|
2021-11-17 23:04:36 +00:00
|
|
|
hitscanwall = nullptr;
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2022-09-13 22:20:58 +00:00
|
|
|
double dist = hitawall(p, &hitscanwall);
|
|
|
|
|
2021-11-17 23:04:36 +00:00
|
|
|
if (hitscanwall != nullptr)
|
2021-11-17 22:40:10 +00:00
|
|
|
{
|
2022-12-10 18:03:17 +00:00
|
|
|
if (dist < 80 && hitscanwall->overtexture == mirrortex)
|
2021-11-17 23:04:36 +00:00
|
|
|
if (hitscanwall->lotag > 0 && S_CheckSoundPlaying(hitscanwall->lotag) == 0 && snum == screenpeek)
|
2021-11-17 22:40:10 +00:00
|
|
|
{
|
2021-11-17 23:04:36 +00:00
|
|
|
S_PlayActorSound(hitscanwall->lotag, pact);
|
2021-11-17 22:40:10 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2021-12-18 14:11:21 +00:00
|
|
|
if (hitscanwall != nullptr && (hitscanwall->cstat & CSTAT_WALL_MASKED))
|
2021-11-17 23:04:36 +00:00
|
|
|
if (hitscanwall->lotag)
|
2021-11-17 22:40:10 +00:00
|
|
|
return;
|
|
|
|
}
|
2020-11-02 23:20:51 +00:00
|
|
|
if (p->newOwner != nullptr)
|
2022-11-25 11:30:40 +00:00
|
|
|
neartag(p->GetActor()->getPrevPosWithOffsetZ(), p->GetActor()->sector(), p->GetActor()->PrevAngles.Yaw, near, 80., NT_Lotag);
|
2020-05-12 11:43:24 +00:00
|
|
|
else
|
|
|
|
{
|
2022-11-25 11:30:40 +00:00
|
|
|
neartag(p->GetActor()->getPosWithOffsetZ(), p->GetActor()->sector(), p->GetActor()->PrevAngles.Yaw, near, 80., NT_Lotag);
|
2021-11-26 17:59:28 +00:00
|
|
|
if (near.actor() == nullptr && near.hitWall == nullptr && near.hitSector == nullptr)
|
2022-11-25 11:30:40 +00:00
|
|
|
neartag(p->GetActor()->getPosWithOffsetZ().plusZ(8), p->GetActor()->sector(), p->GetActor()->PrevAngles.Yaw, near, 80., NT_Lotag);
|
2021-11-26 17:59:28 +00:00
|
|
|
if (near.actor() == nullptr && near.hitWall == nullptr && near.hitSector == nullptr)
|
2022-11-25 11:30:40 +00:00
|
|
|
neartag(p->GetActor()->getPosWithOffsetZ().plusZ(16), p->GetActor()->sector(), p->GetActor()->PrevAngles.Yaw, near, 80., NT_Lotag);
|
2021-11-26 17:59:28 +00:00
|
|
|
if (near.actor() == nullptr && near.hitWall == nullptr && near.hitSector == nullptr)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-11-25 11:30:40 +00:00
|
|
|
neartag(p->GetActor()->getPosWithOffsetZ().plusZ(16), p->GetActor()->sector(), p->GetActor()->PrevAngles.Yaw, near, 80., NT_Lotag | NT_Hitag);
|
2021-11-26 17:59:28 +00:00
|
|
|
if (near.actor() != nullptr)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-12-20 21:25:48 +00:00
|
|
|
if (near.actor()->flags2 & SFLAG2_TRIGGERRESPAWN)
|
2020-05-12 11:43:24 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-26 17:59:28 +00:00
|
|
|
near.clearObj();
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-26 17:59:28 +00:00
|
|
|
if (p->newOwner == nullptr && near.actor() == nullptr && near.hitWall == nullptr && near.hitSector == nullptr)
|
2021-11-20 23:33:17 +00:00
|
|
|
if (isanunderoperator(p->GetActor()->sector()->lotag))
|
2021-12-30 15:51:56 +00:00
|
|
|
near.hitSector = p->GetActor()->sector();
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2021-11-26 17:59:28 +00:00
|
|
|
if (near.hitSector && (near.hitSector->lotag & 16384))
|
2020-05-12 11:43:24 +00:00
|
|
|
return;
|
|
|
|
|
2021-11-26 17:59:28 +00:00
|
|
|
if (near.actor() == nullptr && near.hitWall == nullptr)
|
2021-11-21 07:56:39 +00:00
|
|
|
if (p->cursector->lotag == 2)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2020-10-23 17:33:54 +00:00
|
|
|
DDukeActor* hit;
|
2022-09-13 22:30:08 +00:00
|
|
|
dist = hitasprite(p->GetActor(), &hit);
|
2021-11-26 17:59:28 +00:00
|
|
|
if (hit) near.hitActor = hit;
|
2022-09-13 22:11:16 +00:00
|
|
|
if (dist > 80) near.hitActor = nullptr;
|
2020-10-23 17:33:54 +00:00
|
|
|
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
|
|
|
|
2021-11-26 17:59:28 +00:00
|
|
|
auto const neartagsprite = near.actor();
|
2020-10-27 06:00:39 +00:00
|
|
|
if (neartagsprite != nullptr)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-12-11 14:42:33 +00:00
|
|
|
if (checkhitswitch(snum, nullptr, neartagsprite)) return;
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2022-12-03 12:57:54 +00:00
|
|
|
if (CallOnUse(neartagsprite, p))
|
|
|
|
return;
|
2022-01-21 00:04:08 +00:00
|
|
|
}
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2021-11-17 23:16:53 +00:00
|
|
|
if (!PlayerInput(snum, SB_OPEN)) return;
|
2022-01-21 00:04:08 +00:00
|
|
|
else if (p->newOwner != nullptr)
|
2021-11-17 23:16:53 +00:00
|
|
|
{
|
2022-01-21 00:04:08 +00:00
|
|
|
clearcameras(p);
|
2020-05-12 11:43:24 +00:00
|
|
|
return;
|
2022-01-21 00:04:08 +00:00
|
|
|
}
|
2020-05-12 11:43:24 +00:00
|
|
|
|
2021-11-26 17:59:28 +00:00
|
|
|
if (near.hitWall == nullptr && near.hitSector == nullptr && near.actor() == nullptr)
|
2022-09-13 22:05:32 +00:00
|
|
|
if (hits(p->GetActor()) < 32)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
|
|
|
if ((krand() & 255) < 16)
|
2020-11-02 19:23:30 +00:00
|
|
|
S_PlayActorSound(DUKE_SEARCH2, pact);
|
|
|
|
else S_PlayActorSound(DUKE_SEARCH, pact);
|
2020-05-12 11:43:24 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-26 17:59:28 +00:00
|
|
|
if (near.hitWall)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-12-10 18:03:17 +00:00
|
|
|
if (near.hitWall->lotag > 0 && isadoorwall(near.hitWall->walltexture))
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2021-11-26 17:59:28 +00:00
|
|
|
if (hitscanwall == near.hitWall || hitscanwall == nullptr)
|
2022-12-11 14:42:33 +00:00
|
|
|
checkhitswitch(snum, near.hitWall, nullptr);
|
2020-05-12 11:43:24 +00:00
|
|
|
return;
|
|
|
|
}
|
2020-11-02 23:20:51 +00:00
|
|
|
else if (p->newOwner != nullptr)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-01-21 00:04:08 +00:00
|
|
|
clearcameras(p);
|
2021-11-17 23:16:53 +00:00
|
|
|
return;
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-26 17:59:28 +00:00
|
|
|
if (near.hitSector && (near.hitSector->lotag & 16384) == 0 && isanearoperator(near.hitSector->lotag))
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2021-11-26 17:59:28 +00:00
|
|
|
DukeSectIterator it(near.hitSector);
|
2020-11-02 18:41:06 +00:00
|
|
|
while (auto act = it.Next())
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-11-20 11:43:24 +00:00
|
|
|
if (isactivator(act) || ismasterswitch(act))
|
2020-05-12 11:43:24 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-11-26 17:59:28 +00:00
|
|
|
operatesectors(near.hitSector, p->GetActor());
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
2021-11-20 23:33:17 +00:00
|
|
|
else if ((p->GetActor()->sector()->lotag & 16384) == 0)
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2021-11-20 23:33:17 +00:00
|
|
|
if (isanunderoperator(p->GetActor()->sector()->lotag))
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2021-11-21 00:04:16 +00:00
|
|
|
DukeSectIterator it(p->GetActor()->sector());
|
2020-11-02 18:41:06 +00:00
|
|
|
while (auto act = it.Next())
|
2020-05-12 11:43:24 +00:00
|
|
|
{
|
2022-11-20 11:43:24 +00:00
|
|
|
if (isactivator(act) || ismasterswitch(act)) return;
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
2021-11-21 00:10:50 +00:00
|
|
|
operatesectors(p->GetActor()->sector(), p->GetActor());
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
2022-12-11 14:42:33 +00:00
|
|
|
else checkhitswitch(snum, near.hitWall, nullptr);
|
2020-05-12 11:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
2020-05-10 20:20:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-10 16:05:36 +00:00
|
|
|
|
2020-05-10 10:42:47 +00:00
|
|
|
|
|
|
|
END_DUKE_NS
|