2019-11-20 16:21:32 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
|
|
|
Copyright (C) 2019 sirlemonhead, Nuke.YKT
|
|
|
|
This file is part of PCExhumed.
|
|
|
|
PCExhumed is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License version 2
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
2019-11-22 23:11:37 +00:00
|
|
|
#include "ns.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "engine.h"
|
|
|
|
#include "exhumed.h"
|
2020-08-18 07:52:08 +00:00
|
|
|
#include "aistuff.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "player.h"
|
|
|
|
#include "view.h"
|
|
|
|
#include "status.h"
|
|
|
|
#include "sound.h"
|
2020-08-23 14:24:54 +00:00
|
|
|
#include "mapinfo.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <assert.h>
|
2020-08-18 08:28:19 +00:00
|
|
|
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-11-22 23:11:37 +00:00
|
|
|
BEGIN_PS_NS
|
|
|
|
|
2021-11-21 19:34:15 +00:00
|
|
|
int nPushBlocks;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
// TODO - moveme?
|
2021-11-22 23:20:15 +00:00
|
|
|
sectortype* overridesect;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-10-11 11:14:32 +00:00
|
|
|
enum
|
|
|
|
{
|
2021-12-07 17:53:02 +00:00
|
|
|
kMaxPushBlocks = 100,
|
|
|
|
kMaxMoveChunks = 75
|
2020-10-11 11:14:32 +00:00
|
|
|
};
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-07 17:53:02 +00:00
|
|
|
|
|
|
|
TObjPtr<DExhumedActor*> nBodySprite[50];
|
|
|
|
TObjPtr<DExhumedActor*> nChunkSprite[kMaxMoveChunks];
|
2019-08-26 03:59:14 +00:00
|
|
|
BlockInfo sBlockInfo[kMaxPushBlocks];
|
2021-12-07 17:53:02 +00:00
|
|
|
TObjPtr<DExhumedActor*> nBodyGunSprite[50];
|
|
|
|
int nCurBodyGunNum;
|
|
|
|
|
|
|
|
int sprceiling, sprfloor;
|
|
|
|
Collision loHit, hiHit;
|
|
|
|
|
|
|
|
// think this belongs in init.c?
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-07 17:53:02 +00:00
|
|
|
|
|
|
|
size_t MarkMove()
|
|
|
|
{
|
|
|
|
GC::MarkArray(nBodySprite, 50);
|
|
|
|
GC::MarkArray(nChunkSprite, kMaxMoveChunks);
|
|
|
|
for(int i = 0; i < nPushBlocks; i++)
|
|
|
|
GC::Mark(sBlockInfo[i].pActor);
|
|
|
|
return 50 + kMaxMoveChunks + nPushBlocks;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-11-29 23:51:56 +00:00
|
|
|
FSerializer& Serialize(FSerializer& arc, const char* keyname, BlockInfo& w, BlockInfo* def)
|
|
|
|
{
|
|
|
|
if (arc.BeginObject(keyname))
|
|
|
|
{
|
|
|
|
arc("at8", w.field_8)
|
2021-10-22 15:45:06 +00:00
|
|
|
("sprite", w.pActor)
|
2020-11-29 23:51:56 +00:00
|
|
|
("x", w.x)
|
|
|
|
("y", w.y)
|
|
|
|
.EndObject();
|
|
|
|
}
|
|
|
|
return arc;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-11-29 23:51:56 +00:00
|
|
|
void SerializeMove(FSerializer& arc)
|
|
|
|
{
|
|
|
|
if (arc.BeginObject("move"))
|
|
|
|
{
|
2021-11-11 00:09:51 +00:00
|
|
|
arc ("pushcount", nPushBlocks)
|
2020-11-29 23:51:56 +00:00
|
|
|
.Array("blocks", sBlockInfo, nPushBlocks)
|
|
|
|
("chunkcount", nCurChunkNum)
|
|
|
|
.Array("chunks", nChunkSprite, kMaxMoveChunks)
|
|
|
|
("overridesect", overridesect)
|
2021-12-07 17:53:02 +00:00
|
|
|
.Array("bodysprite", nBodySprite, countof(nBodySprite))
|
|
|
|
("curbodygun", nCurBodyGunNum)
|
|
|
|
.Array("bodygunsprite", nBodyGunSprite, countof(nBodyGunSprite))
|
2020-11-29 23:51:56 +00:00
|
|
|
.EndObject();
|
|
|
|
}
|
|
|
|
}
|
2019-12-26 21:00:04 +00:00
|
|
|
|
2019-08-26 03:59:14 +00:00
|
|
|
signed int lsqrt(int a1)
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
int v1;
|
|
|
|
int v2;
|
|
|
|
signed int result;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
v1 = a1;
|
|
|
|
v2 = a1 - 0x40000000;
|
2020-02-04 21:45:10 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
result = 0;
|
2020-02-04 21:45:10 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (v2 >= 0)
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
result = 32768;
|
2019-08-31 07:47:15 +00:00
|
|
|
v1 = v2;
|
|
|
|
}
|
|
|
|
if (v1 - ((result << 15) + 0x10000000) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= (result << 15) + 0x10000000;
|
2020-02-04 21:45:10 +00:00
|
|
|
result += 16384;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
if (v1 - ((result << 14) + 0x4000000) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= (result << 14) + 0x4000000;
|
2020-02-04 21:45:10 +00:00
|
|
|
result += 8192;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
if (v1 - ((result << 13) + 0x1000000) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= (result << 13) + 0x1000000;
|
|
|
|
result += 4096;
|
|
|
|
}
|
|
|
|
if (v1 - ((result << 12) + 0x400000) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= (result << 12) + 0x400000;
|
|
|
|
result += 2048;
|
|
|
|
}
|
|
|
|
if (v1 - ((result << 11) + 0x100000) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= (result << 11) + 0x100000;
|
|
|
|
result += 1024;
|
|
|
|
}
|
|
|
|
if (v1 - ((result << 10) + 0x40000) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= (result << 10) + 0x40000;
|
|
|
|
result += 512;
|
|
|
|
}
|
|
|
|
if (v1 - ((result << 9) + 0x10000) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= (result << 9) + 0x10000;
|
|
|
|
result += 256;
|
|
|
|
}
|
|
|
|
if (v1 - ((result << 8) + 0x4000) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= (result << 8) + 0x4000;
|
|
|
|
result += 128;
|
|
|
|
}
|
|
|
|
if (v1 - ((result << 7) + 4096) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= (result << 7) + 4096;
|
|
|
|
result += 64;
|
|
|
|
}
|
|
|
|
if (v1 - ((result << 6) + 1024) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= (result << 6) + 1024;
|
|
|
|
result += 32;
|
|
|
|
}
|
|
|
|
if (v1 - (32 * result + 256) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= 32 * result + 256;
|
|
|
|
result += 16;
|
|
|
|
}
|
|
|
|
if (v1 - (16 * result + 64) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= 16 * result + 64;
|
|
|
|
result += 8;
|
|
|
|
}
|
|
|
|
if (v1 - (8 * result + 16) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= 8 * result + 16;
|
|
|
|
result += 4;
|
|
|
|
}
|
|
|
|
if (v1 - (4 * result + 4) >= 0)
|
|
|
|
{
|
|
|
|
v1 -= 4 * result + 4;
|
|
|
|
result += 2;
|
|
|
|
}
|
|
|
|
if (v1 - (2 * result + 1) >= 0)
|
2020-02-04 21:45:10 +00:00
|
|
|
result += 1;
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
return result;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MoveThings()
|
|
|
|
{
|
2020-08-28 07:07:36 +00:00
|
|
|
thinktime.Reset();
|
|
|
|
thinktime.Clock();
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
UndoFlashes();
|
|
|
|
DoLights();
|
|
|
|
|
|
|
|
if (nFreeze)
|
|
|
|
{
|
|
|
|
if (nFreeze == 1 || nFreeze == 2) {
|
|
|
|
DoSpiritHead();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-28 07:07:36 +00:00
|
|
|
actortime.Reset();
|
|
|
|
actortime.Clock();
|
2019-08-31 07:47:15 +00:00
|
|
|
runlist_ExecObjects();
|
|
|
|
runlist_CleanRunRecs();
|
2020-08-28 07:07:36 +00:00
|
|
|
actortime.Unclock();
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DoBubbleMachines();
|
|
|
|
DoDrips();
|
|
|
|
DoMovingSects();
|
|
|
|
DoRegenerates();
|
|
|
|
|
2021-05-02 13:54:19 +00:00
|
|
|
if (currentLevel->gameflags & LEVEL_EX_COUNTDOWN)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
DoFinale();
|
|
|
|
if (lCountDown < 1800 && nDronePitch < 2400 && !lFinaleStart)
|
|
|
|
{
|
|
|
|
nDronePitch += 64;
|
|
|
|
BendAmbientSound();
|
|
|
|
}
|
|
|
|
}
|
2020-08-28 07:07:36 +00:00
|
|
|
|
|
|
|
thinktime.Unclock();
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ResetMoveFifo()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
movefifoend = 0;
|
|
|
|
movefifopos = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// not used
|
|
|
|
void clipwall()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-17 21:24:44 +00:00
|
|
|
int BelowNear(DExhumedActor* pActor, double walldist)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-12-30 15:51:56 +00:00
|
|
|
auto pSector = pActor->sector();
|
2022-01-31 22:33:44 +00:00
|
|
|
int z = pActor->int_pos().Z;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-21 21:41:54 +00:00
|
|
|
int z2;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-21 21:41:54 +00:00
|
|
|
if (loHit.type == kHitSprite)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-01-31 22:33:44 +00:00
|
|
|
z2 = loHit.actor()->int_pos().Z;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-02 23:46:04 +00:00
|
|
|
z2 = pSector->int_floorz() + pSector->Depth;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-22 21:38:27 +00:00
|
|
|
BFSSectorSearch search(pSector);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-22 21:38:27 +00:00
|
|
|
sectortype* pTempSect = nullptr;
|
|
|
|
while (auto pCurSector = search.GetNext())
|
2021-11-16 21:51:55 +00:00
|
|
|
{
|
2021-11-22 21:38:27 +00:00
|
|
|
for (auto& wal : wallsofsector(pCurSector))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-11-22 21:38:27 +00:00
|
|
|
if (wal.twoSided())
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-11-22 21:38:27 +00:00
|
|
|
if (!search.Check(wal.nextSector()))
|
2021-11-16 21:51:55 +00:00
|
|
|
{
|
2022-08-17 21:24:44 +00:00
|
|
|
if (IsCloseToWall(pActor->spr.pos, &wal, walldist) != EClose::Outside)
|
2021-11-16 21:51:55 +00:00
|
|
|
{
|
2021-11-22 21:38:27 +00:00
|
|
|
search.Add(wal.nextSector());
|
2021-11-16 21:51:55 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2021-11-16 21:51:55 +00:00
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-22 21:38:27 +00:00
|
|
|
auto pSect2 = pCurSector;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-22 21:38:27 +00:00
|
|
|
while (pSect2)
|
2021-11-16 21:51:55 +00:00
|
|
|
{
|
2021-11-22 21:38:27 +00:00
|
|
|
pTempSect = pSect2;
|
2021-11-22 22:05:48 +00:00
|
|
|
pSect2 = pSect2->pBelow;
|
2021-11-16 21:51:55 +00:00
|
|
|
}
|
|
|
|
|
2022-02-02 23:46:04 +00:00
|
|
|
int ecx = pTempSect->int_floorz() + pTempSect->Depth;
|
2021-11-16 21:51:55 +00:00
|
|
|
int eax = ecx - z;
|
|
|
|
|
|
|
|
if (eax < 0 && eax >= -5120)
|
|
|
|
{
|
|
|
|
z2 = ecx;
|
2021-11-22 21:38:27 +00:00
|
|
|
pSector = pTempSect;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-01-31 22:33:44 +00:00
|
|
|
if (z2 < pActor->int_pos().Z)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-01-31 19:03:22 +00:00
|
|
|
pActor->set_int_z(z2);
|
2021-11-22 23:20:15 +00:00
|
|
|
overridesect = pSector;
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.zvel = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2020-08-18 08:28:19 +00:00
|
|
|
bTouchFloor = true;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-21 21:41:54 +00:00
|
|
|
return kHitAux2;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 21:41:54 +00:00
|
|
|
Collision movespritez(DExhumedActor* pActor, int z, int height, int, int clipdist)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-12-30 15:51:56 +00:00
|
|
|
auto pSector = pActor->sector();
|
2021-11-22 23:13:30 +00:00
|
|
|
assert(pSector);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-22 23:20:15 +00:00
|
|
|
overridesect = pSector;
|
2021-11-22 23:13:30 +00:00
|
|
|
auto pSect2 = pSector;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
// backup cstat
|
2021-12-23 16:04:24 +00:00
|
|
|
auto cstat = pActor->spr.cstat;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.cstat &= ~CSTAT_SPRITE_BLOCK;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-26 13:26:03 +00:00
|
|
|
Collision nRet;
|
|
|
|
nRet.setNone();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-22 23:13:30 +00:00
|
|
|
int nSectFlags = pSector->Flag;
|
2019-09-25 21:16:12 +00:00
|
|
|
|
|
|
|
if (nSectFlags & kSectUnderwater) {
|
2019-08-31 07:47:15 +00:00
|
|
|
z >>= 1;
|
|
|
|
}
|
|
|
|
|
2022-01-31 22:33:44 +00:00
|
|
|
int spriteZ = pActor->int_pos().Z;
|
2022-02-02 23:46:04 +00:00
|
|
|
int floorZ = pSector->int_floorz();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
int ebp = spriteZ + z;
|
2022-02-02 23:46:04 +00:00
|
|
|
int eax = pSector->int_ceilingz() + (height >> 1);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-25 21:16:12 +00:00
|
|
|
if ((nSectFlags & kSectUnderwater) && ebp < eax) {
|
2019-08-31 07:47:15 +00:00
|
|
|
ebp = eax;
|
|
|
|
}
|
|
|
|
|
|
|
|
// loc_151E7:
|
2022-02-02 23:46:04 +00:00
|
|
|
while (ebp > pActor->sector()->int_floorz() && pActor->sector()->pBelow != nullptr)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-30 15:51:56 +00:00
|
|
|
ChangeActorSect(pActor, pActor->sector()->pBelow);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-11-22 23:13:30 +00:00
|
|
|
if (pSect2 != pSector)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-01-31 19:03:22 +00:00
|
|
|
pActor->set_int_z(ebp);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-22 23:13:30 +00:00
|
|
|
if (pSect2->Flag & kSectUnderwater)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-26 07:47:54 +00:00
|
|
|
if (pActor == PlayerList[nLocalPlayer].pActor) {
|
2021-10-21 21:41:54 +00:00
|
|
|
D3PlayFX(StaticSound[kSound2], pActor);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
if (pActor->spr.statnum <= 107) {
|
|
|
|
pActor->spr.hitag = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-09-25 21:16:12 +00:00
|
|
|
else
|
|
|
|
{
|
2022-02-02 23:46:04 +00:00
|
|
|
while ((ebp < pActor->sector()->int_ceilingz()) && (pActor->sector()->pAbove != nullptr))
|
2019-09-25 21:16:12 +00:00
|
|
|
{
|
2021-12-30 15:51:56 +00:00
|
|
|
ChangeActorSect(pActor, pActor->sector()->pAbove);
|
2019-09-25 21:16:12 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
// This function will keep the player from falling off cliffs when you're too close to the edge.
|
|
|
|
// This function finds the highest and lowest z coordinates that your clipping BOX can get to.
|
2022-01-31 22:33:44 +00:00
|
|
|
vec3_t pos = pActor->int_pos();
|
2021-12-22 09:41:47 +00:00
|
|
|
pos.Z -= 256;
|
2021-12-30 15:51:56 +00:00
|
|
|
getzrange(pos, pActor->sector(), &sprceiling, hiHit, &sprfloor, loHit, 128, CLIPMASK0);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
int mySprfloor = sprfloor;
|
|
|
|
|
2021-10-21 21:41:54 +00:00
|
|
|
if (loHit.type != kHitSprite) {
|
2021-12-30 15:51:56 +00:00
|
|
|
mySprfloor += pActor->sector()->Depth;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ebp > mySprfloor)
|
|
|
|
{
|
|
|
|
if (z > 0)
|
|
|
|
{
|
2020-08-18 08:28:19 +00:00
|
|
|
bTouchFloor = true;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-21 21:41:54 +00:00
|
|
|
if (loHit.type == kHitSprite)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-09-25 21:16:12 +00:00
|
|
|
// Path A
|
2021-12-23 17:25:58 +00:00
|
|
|
auto pFloorActor = loHit.actor();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 17:25:58 +00:00
|
|
|
if (pActor->spr.statnum == 100 && pFloorActor->spr.statnum != 0 && pFloorActor->spr.statnum < 100)
|
2019-09-25 21:16:12 +00:00
|
|
|
{
|
2021-11-21 19:34:15 +00:00
|
|
|
int nDamage = (z >> 9);
|
2019-09-25 21:16:12 +00:00
|
|
|
if (nDamage)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-11-26 13:26:03 +00:00
|
|
|
runlist_DamageEnemy(loHit.actor(), pActor, nDamage << 1);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.zvel = -z;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-09-25 21:16:12 +00:00
|
|
|
else
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 17:25:58 +00:00
|
|
|
if (pFloorActor->spr.statnum == 0 || pFloorActor->spr.statnum > 199)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-10-21 21:41:54 +00:00
|
|
|
nRet.exbits |= kHitAux2;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-10-21 21:41:54 +00:00
|
|
|
nRet = loHit;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.zvel = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-09-25 21:16:12 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Path B
|
2021-12-30 15:51:56 +00:00
|
|
|
if (pActor->sector()->pBelow == nullptr)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-10-21 21:41:54 +00:00
|
|
|
nRet.exbits |= kHitAux2;
|
2019-09-25 21:16:12 +00:00
|
|
|
|
2021-12-30 15:51:56 +00:00
|
|
|
int nSectDamage = pActor->sector()->Damage;
|
2019-09-25 21:16:12 +00:00
|
|
|
|
|
|
|
if (nSectDamage != 0)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
if (pActor->spr.hitag < 15)
|
2019-09-25 21:16:12 +00:00
|
|
|
{
|
2021-10-21 21:41:54 +00:00
|
|
|
IgniteSprite(pActor);
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.hitag = 20;
|
2019-09-25 21:16:12 +00:00
|
|
|
}
|
|
|
|
nSectDamage >>= 2;
|
|
|
|
nSectDamage = nSectDamage - (nSectDamage>>2);
|
|
|
|
if (nSectDamage) {
|
2021-10-21 21:41:54 +00:00
|
|
|
runlist_DamageEnemy(pActor, nullptr, nSectDamage);
|
2019-09-25 21:16:12 +00:00
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.zvel = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// loc_1543B:
|
|
|
|
ebp = mySprfloor;
|
2022-01-31 19:03:22 +00:00
|
|
|
pActor->set_int_z(mySprfloor);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-12-30 15:51:56 +00:00
|
|
|
if ((ebp - height) < sprceiling && (hiHit.type == kHitSprite || pActor->sector()->pAbove == nullptr))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
ebp = sprceiling + height;
|
2021-10-21 21:41:54 +00:00
|
|
|
nRet.exbits |= kHitAux1;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (spriteZ <= floorZ && ebp > floorZ)
|
|
|
|
{
|
2021-11-22 23:13:30 +00:00
|
|
|
if ((pSector->Depth != 0) || (pSect2 != pSector && (pSect2->Flag & kSectUnderwater)))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-11-22 21:38:27 +00:00
|
|
|
BuildSplash(pActor, pSector);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.cstat = cstat; // restore cstat
|
2022-01-31 19:03:22 +00:00
|
|
|
pActor->set_int_z(ebp);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
if (pActor->spr.statnum == 100)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-08-17 21:24:44 +00:00
|
|
|
nRet.exbits |= BelowNear(pActor, clipdist * (inttoworld * 1.5));
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nRet;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-15 22:31:28 +00:00
|
|
|
int GetActorHeight(DExhumedActor* actor)
|
|
|
|
{
|
2021-12-21 22:18:23 +00:00
|
|
|
return tileHeight(actor->spr.picnum) * actor->spr.yrepeat * 4;
|
2021-10-15 22:31:28 +00:00
|
|
|
}
|
|
|
|
|
2021-12-04 21:04:16 +00:00
|
|
|
DExhumedActor* insertActor(sectortype* s, int st)
|
2021-10-15 22:31:28 +00:00
|
|
|
{
|
2021-12-06 16:00:15 +00:00
|
|
|
return static_cast<DExhumedActor*>(::InsertActor(RUNTIME_CLASS(DExhumedActor), s, st));
|
2021-10-15 22:31:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-21 18:25:15 +00:00
|
|
|
Collision movesprite(DExhumedActor* pActor, int dx, int dy, int dz, int ceildist, int flordist, unsigned int clipmask)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2020-08-18 08:28:19 +00:00
|
|
|
bTouchFloor = false;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-08-29 20:30:11 +00:00
|
|
|
auto spos = pActor->spr.pos;
|
2019-11-20 16:21:32 +00:00
|
|
|
|
2021-10-21 18:25:15 +00:00
|
|
|
int nSpriteHeight = GetActorHeight(pActor);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
int nClipDist = (int8_t)pActor->spr.clipdist << 2;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-30 15:51:56 +00:00
|
|
|
auto pSector = pActor->sector();
|
2021-11-22 23:47:25 +00:00
|
|
|
assert(pSector);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-08-29 20:30:11 +00:00
|
|
|
double floorZ = pSector->floorz;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-08-29 20:30:11 +00:00
|
|
|
if ((pSector->Flag & kSectUnderwater) || (floorZ < spos.Z))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
dx >>= 1;
|
|
|
|
dy >>= 1;
|
|
|
|
}
|
|
|
|
|
2021-10-21 21:41:54 +00:00
|
|
|
Collision nRet = movespritez(pActor, dz, nSpriteHeight, flordist, nClipDist);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-30 15:51:56 +00:00
|
|
|
pSector = pActor->sector(); // modified in movespritez so re-grab this variable
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
if (pActor->spr.statnum == 100)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-11-16 17:50:02 +00:00
|
|
|
int nPlayer = GetPlayerFromActor(pActor);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
int varA = 0;
|
|
|
|
int varB = 0;
|
|
|
|
|
2022-01-31 22:33:44 +00:00
|
|
|
CheckSectorFloor(overridesect, pActor->int_pos().Z, &varB, &varA);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
if (varB || varA)
|
|
|
|
{
|
2021-12-30 12:10:12 +00:00
|
|
|
PlayerList[nPlayer].nDamage.X = varB;
|
|
|
|
PlayerList[nPlayer].nDamage.Y = varA;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-12-30 12:10:12 +00:00
|
|
|
dx += PlayerList[nPlayer].nDamage.X;
|
|
|
|
dy += PlayerList[nPlayer].nDamage.Y;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-01-31 22:33:44 +00:00
|
|
|
CheckSectorFloor(overridesect, pActor->int_pos().Z, &dx, &dy);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-11-26 13:26:03 +00:00
|
|
|
Collision coll;
|
2022-08-30 19:36:09 +00:00
|
|
|
clipmove(pActor->spr.pos, &pSector, dx, dy, nClipDist, nSpriteHeight, flordist, clipmask, coll);
|
2021-10-21 21:41:54 +00:00
|
|
|
if (coll.type != kHitNone) // originally this or'ed the two values which can create unpredictable bad values in some edge cases.
|
|
|
|
{
|
|
|
|
coll.exbits = nRet.exbits;
|
|
|
|
nRet = coll;
|
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-30 15:51:56 +00:00
|
|
|
if ((pSector != pActor->sector()) && pSector != nullptr)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-10-21 21:41:54 +00:00
|
|
|
if (nRet.exbits & kHitAux2) {
|
2019-08-31 07:47:15 +00:00
|
|
|
dz = 0;
|
|
|
|
}
|
2019-11-20 16:21:32 +00:00
|
|
|
|
2022-08-29 20:30:11 +00:00
|
|
|
if ((pSector->floorz - spos.Z) < (dz + flordist) * zinttoworld)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-08-29 20:30:11 +00:00
|
|
|
pActor->spr.pos.XY() = spos.XY();
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-11-22 23:47:25 +00:00
|
|
|
ChangeActorSect(pActor, pSector);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
if (pActor->spr.pal < 5 && !pActor->spr.hitag)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-30 15:51:56 +00:00
|
|
|
pActor->spr.pal = pActor->sector()->ceilingpal;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 21:41:54 +00:00
|
|
|
return nRet;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-12-23 15:44:43 +00:00
|
|
|
void Gravity(DExhumedActor* pActor)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-12-30 15:51:56 +00:00
|
|
|
if (pActor->sector()->Flag & kSectUnderwater)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
if (pActor->spr.statnum != 100)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
if (pActor->spr.zvel <= 1024)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
if (pActor->spr.zvel < 2048) {
|
|
|
|
pActor->spr.zvel += 512;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.zvel -= 64;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
if (pActor->spr.zvel > 0)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.zvel -= 64;
|
|
|
|
if (pActor->spr.zvel < 0) {
|
|
|
|
pActor->spr.zvel = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
2021-12-23 16:04:24 +00:00
|
|
|
else if (pActor->spr.zvel < 0)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.zvel += 64;
|
|
|
|
if (pActor->spr.zvel > 0) {
|
|
|
|
pActor->spr.zvel = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.zvel += 512;
|
|
|
|
if (pActor->spr.zvel > 16384) {
|
|
|
|
pActor->spr.zvel = 16384;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 18:25:15 +00:00
|
|
|
Collision MoveCreature(DExhumedActor* pActor)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
return movesprite(pActor, pActor->spr.xvel << 8, pActor->spr.yvel << 8, pActor->spr.zvel, 15360, -5120, CLIPMASK0);
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 18:25:15 +00:00
|
|
|
Collision MoveCreatureWithCaution(DExhumedActor* pActor)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2022-08-16 22:18:47 +00:00
|
|
|
auto oldv = pActor->spr.pos;
|
2021-12-30 15:51:56 +00:00
|
|
|
auto pSectorPre = pActor->sector();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-21 18:25:15 +00:00
|
|
|
auto ecx = MoveCreature(pActor);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-30 15:51:56 +00:00
|
|
|
auto pSector =pActor->sector();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-20 19:52:29 +00:00
|
|
|
if (pSector != pSectorPre)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-02-02 23:46:04 +00:00
|
|
|
int zDiff = pSectorPre->int_floorz() - pSector->int_floorz();
|
2019-08-31 07:47:15 +00:00
|
|
|
if (zDiff < 0) {
|
|
|
|
zDiff = -zDiff;
|
|
|
|
}
|
|
|
|
|
2021-11-22 22:05:48 +00:00
|
|
|
if (zDiff > 15360 || (pSector->Flag & kSectUnderwater) || (pSector->pBelow != nullptr && pSector->pBelow->Flag) || pSector->Damage)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-08-16 22:18:47 +00:00
|
|
|
pActor->spr.pos = oldv;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-22 22:35:11 +00:00
|
|
|
ChangeActorSect(pActor, pSectorPre);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-08-16 21:21:10 +00:00
|
|
|
pActor->set_int_ang((pActor->int_ang() + 256) & kAngleMask);
|
2022-08-16 21:17:01 +00:00
|
|
|
pActor->spr.xvel = bcos(pActor->int_ang(), -2);
|
|
|
|
pActor->spr.yvel = bsin(pActor->int_ang(), -2);
|
2021-11-26 13:26:03 +00:00
|
|
|
Collision c;
|
|
|
|
c.setNone();
|
|
|
|
return c;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ecx;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-20 21:02:23 +00:00
|
|
|
int GetAngleToSprite(DExhumedActor* a1, DExhumedActor* a2)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-10-20 21:02:23 +00:00
|
|
|
if (!a1 || !a2)
|
2019-08-31 07:47:15 +00:00
|
|
|
return -1;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-20 15:07:56 +00:00
|
|
|
return getangle(a2->spr.pos - a1->spr.pos);
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 18:06:49 +00:00
|
|
|
int PlotCourseToSprite(DExhumedActor* pActor1, DExhumedActor* pActor2)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-10-21 18:06:49 +00:00
|
|
|
if (pActor1 == nullptr || pActor2 == nullptr)
|
2019-08-31 07:47:15 +00:00
|
|
|
return -1;
|
2022-08-20 15:07:56 +00:00
|
|
|
|
|
|
|
auto vect = pActor2->spr.pos.XY() - pActor1->spr.pos.XY();
|
|
|
|
pActor1->spr.angle = VecToAngle(vect);
|
|
|
|
return int(vect.Length() * worldtoint);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-10-21 18:06:49 +00:00
|
|
|
DExhumedActor* FindPlayer(DExhumedActor* pActor, int nDistance, bool dontengage)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-10-21 18:06:49 +00:00
|
|
|
int var_18 = !dontengage;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
if (nDistance < 0)
|
|
|
|
nDistance = 100;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-22 16:40:37 +00:00
|
|
|
auto pSector =pActor->sector();
|
|
|
|
nDistance <<= 4;
|
2019-11-20 16:21:32 +00:00
|
|
|
|
2021-10-21 18:06:49 +00:00
|
|
|
DExhumedActor* pPlayerActor = nullptr;
|
2019-08-31 07:47:15 +00:00
|
|
|
int i = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
if (i >= nTotalPlayers)
|
2021-10-21 18:06:49 +00:00
|
|
|
return nullptr;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-26 07:47:54 +00:00
|
|
|
pPlayerActor = PlayerList[i].pActor;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-23 17:25:58 +00:00
|
|
|
if ((pPlayerActor->spr.cstat & CSTAT_SPRITE_BLOCK_ALL) && (!(pPlayerActor->spr.cstat & CSTAT_SPRITE_INVISIBLE)))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-08-22 16:40:37 +00:00
|
|
|
int v9 = abs(pPlayerActor->spr.pos.X - pActor->spr.pos.X);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
if (v9 < nDistance)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-08-22 16:40:37 +00:00
|
|
|
int v10 = abs(pPlayerActor->spr.pos.Y - pActor->spr.pos.Y);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-22 16:40:37 +00:00
|
|
|
if (v10 < nDistance && cansee(pPlayerActor->spr.pos.plusZ(-30), pPlayerActor->sector(), pActor->spr.pos.plusZ(-GetActorHeightF(pActor)), pSector))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
i++;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (var_18) {
|
2021-10-21 18:06:49 +00:00
|
|
|
PlotCourseToSprite(pActor, pPlayerActor);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-10-21 18:06:49 +00:00
|
|
|
return pPlayerActor;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-11-22 23:20:15 +00:00
|
|
|
void CheckSectorFloor(sectortype* pSector, int z, int *x, int *y)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-11-20 19:52:29 +00:00
|
|
|
int nSpeed = pSector->Speed;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
if (!nSpeed) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-21 19:34:15 +00:00
|
|
|
int nFlag = pSector->Flag;
|
|
|
|
int nAng = nFlag & kAngleMask;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-02-02 23:46:04 +00:00
|
|
|
if (z >= pSector->int_floorz())
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2020-11-14 08:45:08 +00:00
|
|
|
*x += bcos(nAng, 3) * nSpeed;
|
|
|
|
*y += bsin(nAng, 3) * nSpeed;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else if (nFlag & 0x800)
|
|
|
|
{
|
2020-11-14 08:45:08 +00:00
|
|
|
*x += bcos(nAng, 4) * nSpeed;
|
|
|
|
*y += bsin(nAng, 4) * nSpeed;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 18:06:49 +00:00
|
|
|
int GetUpAngle(DExhumedActor* pActor1, int nVal, DExhumedActor* pActor2, int ecx)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2022-01-31 22:33:44 +00:00
|
|
|
int x = pActor2->int_pos().X - pActor1->int_pos().X;
|
|
|
|
int y = pActor2->int_pos().Y - pActor1->int_pos().Y;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-01-31 22:33:44 +00:00
|
|
|
int ebx = (pActor2->int_pos().Z + ecx) - (pActor1->int_pos().Z + nVal);
|
|
|
|
int edx = (pActor2->int_pos().Z + ecx) - (pActor1->int_pos().Z + nVal);
|
2019-11-20 16:21:32 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
ebx >>= 4;
|
|
|
|
edx >>= 8;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
ebx = -ebx;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
ebx -= edx;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int nSqrt = lsqrt(x * x + y * y);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-20 14:55:48 +00:00
|
|
|
return getangle(nSqrt, ebx);
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InitPushBlocks()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nPushBlocks = 0;
|
2021-12-07 18:05:40 +00:00
|
|
|
memset(sBlockInfo, 0, sizeof(sBlockInfo));
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int GrabPushBlock()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
if (nPushBlocks >= kMaxPushBlocks) {
|
|
|
|
return -1;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
return nPushBlocks++;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-11-22 23:03:18 +00:00
|
|
|
void CreatePushBlock(sectortype* pSector)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
int nBlock = GrabPushBlock();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-30 20:16:18 +00:00
|
|
|
double xSumm = 0;
|
|
|
|
double ySumm = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-11-22 23:03:18 +00:00
|
|
|
for (auto& wal : wallsofsector(pSector))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-08-30 20:16:18 +00:00
|
|
|
xSumm += wal.pos.X;
|
|
|
|
ySumm += wal.pos.Y;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-30 20:16:18 +00:00
|
|
|
double xAvgg = xSumm / pSector->wallnum;
|
|
|
|
double yAvgg = ySumm / pSector->wallnum;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-30 20:16:18 +00:00
|
|
|
sBlockInfo[nBlock].x = xAvgg * worldtoint;
|
|
|
|
sBlockInfo[nBlock].y = yAvgg * worldtoint;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-11-22 23:03:18 +00:00
|
|
|
auto pActor = insertActor(pSector, 0);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-10-22 15:45:06 +00:00
|
|
|
sBlockInfo[nBlock].pActor = pActor;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-30 20:16:18 +00:00
|
|
|
pActor->spr.pos = { xAvgg, yAvgg, pSector->floorz- 1 };
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.cstat = CSTAT_SPRITE_INVISIBLE;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-30 20:16:18 +00:00
|
|
|
double mindist = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-11-22 23:03:18 +00:00
|
|
|
for (auto& wal : wallsofsector(pSector))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-08-30 20:16:18 +00:00
|
|
|
double xDiff = abs(xAvgg - wal.pos.X);
|
|
|
|
double yDiff = abs(yAvgg - wal.pos.Y);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-30 20:16:18 +00:00
|
|
|
double nSqrt = g_sqrt(xDiff * xDiff + yDiff * yDiff);
|
2020-06-22 10:24:21 +00:00
|
|
|
|
2022-08-30 20:16:18 +00:00
|
|
|
if (nSqrt > mindist) {
|
|
|
|
mindist = nSqrt;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-30 20:16:18 +00:00
|
|
|
sBlockInfo[nBlock].field_8 = mindist * worldtoint;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-30 20:16:18 +00:00
|
|
|
pActor->spr.clipdist = (int(mindist * worldtoint) & 0xFF) << 2;
|
2021-11-22 23:03:18 +00:00
|
|
|
pSector->extra = nBlock;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-11-22 20:03:10 +00:00
|
|
|
void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-11-22 20:03:10 +00:00
|
|
|
if (pSector == nullptr) {
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int nXVect, nYVect;
|
|
|
|
|
|
|
|
if (nAngle < 0)
|
|
|
|
{
|
|
|
|
nXVect = *nXVel;
|
|
|
|
nYVect = *nYVel;
|
2022-08-20 14:55:48 +00:00
|
|
|
nAngle = getangle(nXVect, nYVect);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-11-14 08:45:08 +00:00
|
|
|
nXVect = bcos(nAngle, 6);
|
|
|
|
nYVect = bsin(nAngle, 6);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-11-21 19:34:15 +00:00
|
|
|
int nBlock = pSector->extra;
|
2021-11-22 20:03:10 +00:00
|
|
|
int nSectFlag = pSector->Flag;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-02-02 23:46:04 +00:00
|
|
|
int nFloorZ = pSector->int_floorz();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-21 08:31:40 +00:00
|
|
|
walltype *pStartWall = pSector->firstWall();
|
|
|
|
sectortype* pNextSector = pStartWall->nextSector();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
BlockInfo *pBlockInfo = &sBlockInfo[nBlock];
|
|
|
|
|
2021-10-30 10:26:42 +00:00
|
|
|
vec3_t pos;
|
|
|
|
|
2021-12-22 09:36:09 +00:00
|
|
|
pos.X = sBlockInfo[nBlock].x;
|
2019-08-31 07:47:15 +00:00
|
|
|
int x_b = sBlockInfo[nBlock].x;
|
|
|
|
|
2021-12-22 09:40:26 +00:00
|
|
|
pos.Y = sBlockInfo[nBlock].y;
|
2019-08-31 07:47:15 +00:00
|
|
|
int y_b = sBlockInfo[nBlock].y;
|
|
|
|
|
|
|
|
|
|
|
|
int nZVal;
|
|
|
|
|
|
|
|
int bUnderwater = nSectFlag & kSectUnderwater;
|
|
|
|
|
|
|
|
if (nSectFlag & kSectUnderwater)
|
|
|
|
{
|
2022-02-02 23:46:04 +00:00
|
|
|
nZVal = pSector->int_ceilingz();
|
|
|
|
pos.Z = pNextSector->int_ceilingz() + 256;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-08-20 18:57:54 +00:00
|
|
|
pSector->setceilingz(pNextSector->ceilingz);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-02 23:46:04 +00:00
|
|
|
nZVal = pSector->int_floorz();
|
|
|
|
pos.Z = pNextSector->int_floorz() - 256;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-08-20 18:25:38 +00:00
|
|
|
pSector->setfloorz(pNextSector->floorz);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-11-22 20:03:10 +00:00
|
|
|
auto pSectorB = pSector;
|
2021-11-26 13:26:03 +00:00
|
|
|
Collision scratch;
|
|
|
|
clipmove(pos, &pSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1, scratch);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-22 09:40:26 +00:00
|
|
|
int yvect = pos.Y - y_b;
|
2021-12-22 09:36:09 +00:00
|
|
|
int xvect = pos.X - x_b;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-22 20:03:10 +00:00
|
|
|
if (pSectorB != pNextSector && pSectorB != pSector)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
yvect = 0;
|
|
|
|
xvect = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!bUnderwater)
|
|
|
|
{
|
2021-10-30 10:26:42 +00:00
|
|
|
pos = { x_b, y_b, nZVal };
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-26 13:26:03 +00:00
|
|
|
clipmove(pos, &pSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1, scratch);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-22 09:36:09 +00:00
|
|
|
int ebx = pos.X;
|
2019-08-31 07:47:15 +00:00
|
|
|
int ecx = x_b;
|
2021-12-22 09:40:26 +00:00
|
|
|
int edx = pos.Y;
|
2019-08-31 07:47:15 +00:00
|
|
|
int eax = xvect;
|
|
|
|
int esi = y_b;
|
|
|
|
|
|
|
|
if (eax < 0) {
|
|
|
|
eax = -eax;
|
|
|
|
}
|
|
|
|
|
|
|
|
ebx -= ecx;
|
|
|
|
ecx = eax;
|
|
|
|
eax = ebx;
|
|
|
|
edx -= esi;
|
|
|
|
|
|
|
|
if (eax < 0) {
|
|
|
|
eax = -eax;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ecx > eax)
|
|
|
|
{
|
|
|
|
xvect = ebx;
|
|
|
|
}
|
|
|
|
|
|
|
|
eax = yvect;
|
|
|
|
if (eax < 0) {
|
|
|
|
eax = -eax;
|
|
|
|
}
|
|
|
|
|
|
|
|
ebx = eax;
|
|
|
|
eax = edx;
|
|
|
|
|
|
|
|
if (eax < 0) {
|
|
|
|
eax = -eax;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ebx > eax) {
|
|
|
|
yvect = edx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GREEN
|
|
|
|
if (yvect || xvect)
|
|
|
|
{
|
2021-11-22 20:03:10 +00:00
|
|
|
ExhumedSectIterator it(pSector);
|
2021-10-20 20:27:16 +00:00
|
|
|
while (auto pActor = it.Next())
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 17:25:58 +00:00
|
|
|
if (pActor->spr.statnum < 99)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-01-31 19:03:22 +00:00
|
|
|
pActor->add_int_pos({ xvect, yvect, 0 });
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-01-31 22:33:44 +00:00
|
|
|
pos.Z = pActor->int_pos().Z;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 17:25:58 +00:00
|
|
|
if ((nSectFlag & kSectUnderwater) || pos.Z != nZVal || pActor->spr.cstat & CSTAT_SPRITE_INVISIBLE)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-01-31 22:33:44 +00:00
|
|
|
pos.X = pActor->int_pos().X;
|
|
|
|
pos.Y = pActor->int_pos().Y;
|
2021-11-22 20:03:10 +00:00
|
|
|
pSectorB = pSector;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 17:25:58 +00:00
|
|
|
clipmove(pos, &pSectorB, -xvect, -yvect, 4 * pActor->spr.clipdist, 0, 0, CLIPMASK0, scratch);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-22 20:03:10 +00:00
|
|
|
if (pSectorB) {
|
|
|
|
ChangeActorSect(pActor, pSectorB);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-11-21 08:31:40 +00:00
|
|
|
it.Reset(pNextSector);
|
2021-10-20 20:27:16 +00:00
|
|
|
while (auto pActor = it.Next())
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
if (pActor->spr.statnum >= 99)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-01-31 22:33:44 +00:00
|
|
|
pos = pActor->int_pos();
|
2021-11-22 20:03:10 +00:00
|
|
|
pSectorB = pNextSector;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-26 13:26:03 +00:00
|
|
|
clipmove(pos, &pSectorB,
|
2021-12-23 16:04:24 +00:00
|
|
|
-xvect - (bcos(nAngle) * (4 * pActor->spr.clipdist)),
|
|
|
|
-yvect - (bsin(nAngle) * (4 * pActor->spr.clipdist)),
|
|
|
|
4 * pActor->spr.clipdist, 0, 0, CLIPMASK0, scratch);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
|
2021-11-22 20:03:10 +00:00
|
|
|
if (pSectorB != pNextSector && (pSectorB == pSector || pNextSector == pSector))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-01-31 22:33:44 +00:00
|
|
|
if (pSectorB != pSector || nFloorZ >= pActor->int_pos().Z)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-11-22 20:03:10 +00:00
|
|
|
if (pSectorB) {
|
|
|
|
ChangeActorSect(pActor, pSectorB);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-10-20 20:27:16 +00:00
|
|
|
movesprite(pActor,
|
2021-12-23 16:04:24 +00:00
|
|
|
(xvect << 14) + bcos(nAngle) * pActor->spr.clipdist,
|
|
|
|
(yvect << 14) + bsin(nAngle) * pActor->spr.clipdist,
|
2019-08-31 07:47:15 +00:00
|
|
|
0, 0, 0, CLIPMASK0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-21 08:31:40 +00:00
|
|
|
for(auto& wal : wallsofsector(pSector))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-01-27 16:41:10 +00:00
|
|
|
dragpoint(&wal, xvect + wal.wall_int_pos().X, yvect + wal.wall_int_pos().Y);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pBlockInfo->x += xvect;
|
|
|
|
pBlockInfo->y += yvect;
|
|
|
|
}
|
|
|
|
|
|
|
|
// loc_163DD
|
|
|
|
xvect <<= 14;
|
|
|
|
yvect <<= 14;
|
|
|
|
|
|
|
|
if (!(nSectFlag & kSectUnderwater))
|
|
|
|
{
|
2021-11-22 20:03:10 +00:00
|
|
|
ExhumedSectIterator it(pSector);
|
2021-10-20 20:27:16 +00:00
|
|
|
while (auto pActor = it.Next())
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-01-31 22:33:44 +00:00
|
|
|
if (pActor->spr.statnum >= 99 && nZVal == pActor->int_pos().Z && !(pActor->spr.cstat & CSTAT_SPRITE_INVISIBLE))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-11-22 20:03:10 +00:00
|
|
|
pSectorB = pSector;
|
2022-08-30 19:36:09 +00:00
|
|
|
clipmove(pActor->spr.pos, &pSectorB, xvect, yvect, 4 * pActor->spr.clipdist, 5120, -5120, CLIPMASK0, scratch);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nSectFlag & kSectUnderwater) {
|
2022-02-02 23:35:12 +00:00
|
|
|
pSector->set_int_ceilingz(nZVal);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else {
|
2022-02-02 23:35:12 +00:00
|
|
|
pSector->set_int_floorz(nZVal);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*nXVel = xvect;
|
|
|
|
*nYVel = yvect;
|
2020-05-26 00:13:39 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
Update player position variables, in case the player sprite was moved by a sector,
|
|
|
|
Otherwise these can be out of sync when used in sound code (before being updated in PlayerFunc()).
|
|
|
|
Can cause local player sounds to play off-centre.
|
|
|
|
TODO: Might need to be done elsewhere too?
|
|
|
|
*/
|
2021-12-26 07:47:54 +00:00
|
|
|
auto pActor = PlayerList[nLocalPlayer].pActor;
|
2022-08-23 21:36:23 +00:00
|
|
|
initpos = pActor->spr.pos;
|
2022-08-16 21:17:01 +00:00
|
|
|
inita = pActor->int_ang();
|
2021-12-30 15:51:56 +00:00
|
|
|
initsectp = pActor->sector();
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 19:10:17 +00:00
|
|
|
void SetQuake(DExhumedActor* pActor, int nVal)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2022-01-31 22:33:44 +00:00
|
|
|
int x = pActor->int_pos().X;
|
|
|
|
int y = pActor->int_pos().Y;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
nVal *= 256;
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
for (int i = 0; i < nTotalPlayers; i++)
|
|
|
|
{
|
2021-12-26 07:47:54 +00:00
|
|
|
auto pPlayerActor = PlayerList[i].pActor;
|
2021-10-21 20:39:17 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-01-31 22:33:44 +00:00
|
|
|
uint32_t xDiff = abs((int32_t)((pPlayerActor->int_pos().X - x) >> 8));
|
|
|
|
uint32_t yDiff = abs((int32_t)((pPlayerActor->int_pos().Y - y) >> 8));
|
2020-06-22 10:24:21 +00:00
|
|
|
|
|
|
|
uint32_t sqrtNum = xDiff * xDiff + yDiff * yDiff;
|
|
|
|
|
|
|
|
if (sqrtNum > INT_MAX)
|
|
|
|
{
|
2020-09-08 16:48:18 +00:00
|
|
|
DPrintf(DMSG_WARNING, "%s %d: overflow\n", __func__, __LINE__);
|
2020-06-22 10:24:21 +00:00
|
|
|
sqrtNum = INT_MAX;
|
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2020-06-22 10:24:21 +00:00
|
|
|
int nSqrt = ksqrt(sqrtNum);
|
2020-02-04 21:45:10 +00:00
|
|
|
|
|
|
|
int eax = nVal;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
if (nSqrt)
|
|
|
|
{
|
|
|
|
eax = eax / nSqrt;
|
|
|
|
|
|
|
|
if (eax >= 256)
|
|
|
|
{
|
|
|
|
if (eax > 3840) {
|
|
|
|
eax = 3840;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
eax = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (eax > nQuake[i]) {
|
|
|
|
nQuake[i] = eax;
|
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 17:57:46 +00:00
|
|
|
Collision AngleChase(DExhumedActor* pActor, DExhumedActor* pActor2, int ebx, int ecx, int push1)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
int nClipType = pActor->spr.statnum != 107;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
/* bjd - need to handle cliptype to clipmask change that occured in later build engine version */
|
|
|
|
if (nClipType == 1) {
|
|
|
|
nClipType = CLIPMASK1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nClipType = CLIPMASK0;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-11-16 17:41:34 +00:00
|
|
|
int nAngle;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-10-21 17:57:46 +00:00
|
|
|
if (pActor2 == nullptr)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.zvel = 0;
|
2022-08-16 21:17:01 +00:00
|
|
|
nAngle = pActor->int_ang();
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-12-23 17:25:58 +00:00
|
|
|
int nHeight = tileHeight(pActor2->spr.picnum) * pActor2->spr.yrepeat * 2;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-20 15:07:56 +00:00
|
|
|
auto vect = pActor2->spr.pos.XY() - pActor->spr.pos.XY();
|
|
|
|
int nMyAngle = getangle(vect);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-20 15:07:56 +00:00
|
|
|
int nSqrt = int(vect.Length() * worldtoint);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-20 14:55:48 +00:00
|
|
|
int var_18 = getangle(nSqrt, ((pActor2->int_pos().Z - nHeight) - pActor->int_pos().Z) >> 8);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-16 21:17:01 +00:00
|
|
|
int nAngDelta = AngleDelta(pActor->int_ang(), nMyAngle, 1024);
|
2021-01-04 12:02:00 +00:00
|
|
|
int nAngDelta2 = abs(nAngDelta);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (nAngDelta2 > 63)
|
|
|
|
{
|
2021-01-04 12:02:00 +00:00
|
|
|
nAngDelta2 = abs(nAngDelta >> 6);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
ebx /= nAngDelta2;
|
2019-11-20 16:21:32 +00:00
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
if (ebx < 5) {
|
2019-08-31 07:47:15 +00:00
|
|
|
ebx = 5;
|
2020-02-04 21:45:10 +00:00
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-01-04 12:02:00 +00:00
|
|
|
int nAngDeltaC = abs(nAngDelta);
|
2019-11-20 16:21:32 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (nAngDeltaC > push1)
|
|
|
|
{
|
|
|
|
if (nAngDelta >= 0)
|
|
|
|
nAngDelta = push1;
|
|
|
|
else
|
|
|
|
nAngDelta = -push1;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-16 21:17:01 +00:00
|
|
|
nAngle = (nAngDelta + pActor->int_ang()) & kAngleMask;
|
2021-12-23 16:04:24 +00:00
|
|
|
int nAngDeltaD = AngleDelta(pActor->spr.zvel, var_18, 24);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.zvel = (pActor->spr.zvel + nAngDeltaD) & kAngleMask;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-16 21:21:10 +00:00
|
|
|
pActor->set_int_ang(nAngle);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
int eax = abs(bcos(pActor->spr.zvel));
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-11-14 08:45:08 +00:00
|
|
|
int x = ((bcos(nAngle) * ebx) >> 14) * eax;
|
|
|
|
int y = ((bsin(nAngle) * ebx) >> 14) * eax;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
int xshift = x >> 8;
|
|
|
|
int yshift = y >> 8;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-06-22 10:24:21 +00:00
|
|
|
uint32_t sqrtNum = xshift * xshift + yshift * yshift;
|
|
|
|
|
|
|
|
if (sqrtNum > INT_MAX)
|
|
|
|
{
|
2020-09-08 16:48:18 +00:00
|
|
|
DPrintf(DMSG_WARNING, "%s %d: overflow\n", __func__, __LINE__);
|
2020-06-22 10:24:21 +00:00
|
|
|
sqrtNum = INT_MAX;
|
|
|
|
}
|
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
int z = bsin(pActor->spr.zvel) * ksqrt(sqrtNum);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-10-21 17:57:46 +00:00
|
|
|
return movesprite(pActor, x >> 2, y >> 2, (z >> 13) + bsin(ecx, -5), 0, 0, nClipType);
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-11-22 21:20:53 +00:00
|
|
|
int GetWallNormal(walltype* pWall)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2022-08-30 21:04:39 +00:00
|
|
|
auto delta = pWall->int_delta();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2022-08-20 14:55:48 +00:00
|
|
|
int nAngle = getangle(delta.X, delta.Y);
|
2019-08-31 07:47:15 +00:00
|
|
|
return (nAngle + 512) & kAngleMask;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2022-08-20 13:42:53 +00:00
|
|
|
DVector3 WheresMyMouth(int nPlayer, sectortype **sectnum)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-12-26 07:47:54 +00:00
|
|
|
auto pActor = PlayerList[nPlayer].pActor;
|
2022-10-11 22:17:17 +00:00
|
|
|
double height = GetActorHeight(pActor) * 0.5;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-30 15:51:56 +00:00
|
|
|
*sectnum = pActor->sector();
|
2022-08-20 13:42:53 +00:00
|
|
|
auto pos = pActor->spr.pos.plusZ(-height * zinttoworld);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-11-26 13:26:03 +00:00
|
|
|
Collision scratch;
|
2022-08-20 13:42:53 +00:00
|
|
|
clipmove(pos, sectnum,
|
2022-08-16 21:17:01 +00:00
|
|
|
bcos(pActor->int_ang(), 7),
|
|
|
|
bsin(pActor->int_ang(), 7),
|
2021-11-26 13:26:03 +00:00
|
|
|
5120, 1280, 1280, CLIPMASK1, scratch);
|
2022-08-20 13:42:53 +00:00
|
|
|
return pos;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InitChunks()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nCurChunkNum = 0;
|
2021-09-17 07:24:14 +00:00
|
|
|
memset(nChunkSprite, 0, sizeof(nChunkSprite));
|
2021-09-17 13:33:07 +00:00
|
|
|
memset(nBodyGunSprite, 0, sizeof(nBodyGunSprite));
|
2021-09-17 07:01:17 +00:00
|
|
|
memset(nBodySprite, 0, sizeof(nBodySprite));
|
2019-08-31 07:47:15 +00:00
|
|
|
nCurBodyNum = 0;
|
|
|
|
nCurBodyGunNum = 0;
|
|
|
|
nBodyTotal = 0;
|
|
|
|
nChunkTotal = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-09-17 13:33:07 +00:00
|
|
|
DExhumedActor* GrabBodyGunSprite()
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-12-07 17:53:02 +00:00
|
|
|
DExhumedActor* pActor = nBodyGunSprite[nCurBodyGunNum];
|
2021-09-17 13:33:07 +00:00
|
|
|
if (pActor == nullptr)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-09-17 13:33:07 +00:00
|
|
|
pActor = insertActor(0, 899);
|
|
|
|
nBodyGunSprite[nCurBodyGunNum] = pActor;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.lotag = -1;
|
2022-05-23 22:30:41 +00:00
|
|
|
pActor->spr.intowner = -1;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-10-24 18:21:27 +00:00
|
|
|
DestroyAnim(pActor);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.lotag = -1;
|
2022-05-23 22:30:41 +00:00
|
|
|
pActor->spr.intowner = -1;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nCurBodyGunNum++;
|
|
|
|
if (nCurBodyGunNum >= 50) { // TODO - enum/define
|
|
|
|
nCurBodyGunNum = 0;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.cstat = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-09-17 13:33:07 +00:00
|
|
|
return pActor;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-09-17 07:24:14 +00:00
|
|
|
DExhumedActor* GrabBody()
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-09-17 07:01:17 +00:00
|
|
|
DExhumedActor* pActor = nullptr;
|
2019-08-31 07:47:15 +00:00
|
|
|
do
|
|
|
|
{
|
2021-09-17 07:01:17 +00:00
|
|
|
pActor = nBodySprite[nCurBodyNum];
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-09-17 07:01:17 +00:00
|
|
|
if (pActor == nullptr)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-09-17 07:01:17 +00:00
|
|
|
pActor = insertActor(0, 899);
|
|
|
|
nBodySprite[nCurBodyNum] = pActor;
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.cstat = CSTAT_SPRITE_INVISIBLE;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2021-09-17 07:01:17 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
nCurBodyNum++;
|
|
|
|
if (nCurBodyNum >= 50) {
|
|
|
|
nCurBodyNum = 0;
|
|
|
|
}
|
2021-12-23 16:04:24 +00:00
|
|
|
} while (pActor->spr.cstat & CSTAT_SPRITE_BLOCK_ALL);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
if (nBodyTotal < 50) {
|
|
|
|
nBodyTotal++;
|
|
|
|
}
|
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.cstat = 0;
|
2021-09-17 07:01:17 +00:00
|
|
|
return pActor;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-09-17 07:24:14 +00:00
|
|
|
DExhumedActor* GrabChunkSprite()
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-12-07 17:53:02 +00:00
|
|
|
DExhumedActor* pActor = nChunkSprite[nCurChunkNum];
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-09-17 07:24:14 +00:00
|
|
|
if (pActor == nullptr)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-09-17 07:24:14 +00:00
|
|
|
pActor = insertActor(0, 899);
|
|
|
|
nChunkSprite[nCurChunkNum] = pActor;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2021-12-21 22:18:23 +00:00
|
|
|
else if (pActor->spr.statnum)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-08-26 03:59:14 +00:00
|
|
|
// TODO MonoOut("too many chunks being used at once!\n");
|
2021-09-17 07:24:14 +00:00
|
|
|
return nullptr;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-09-17 07:24:14 +00:00
|
|
|
ChangeActorStat(pActor, 899);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nCurChunkNum++;
|
2020-10-11 09:33:28 +00:00
|
|
|
if (nCurChunkNum >= kMaxMoveChunks)
|
2019-08-31 07:47:15 +00:00
|
|
|
nCurChunkNum = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-10-11 09:33:28 +00:00
|
|
|
if (nChunkTotal < kMaxMoveChunks)
|
2019-08-31 07:47:15 +00:00
|
|
|
nChunkTotal++;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-21 22:18:23 +00:00
|
|
|
pActor->spr.cstat = CSTAT_SPRITE_YCENTER;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-09-17 07:24:14 +00:00
|
|
|
return pActor;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 19:10:17 +00:00
|
|
|
DExhumedActor* BuildCreatureChunk(DExhumedActor* pSrc, int nPic, bool bSpecial)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-12-23 15:44:43 +00:00
|
|
|
auto pActor = GrabChunkSprite();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 15:44:43 +00:00
|
|
|
if (pActor == nullptr) {
|
2021-10-21 19:10:17 +00:00
|
|
|
return nullptr;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2022-08-16 21:46:18 +00:00
|
|
|
pActor->spr.pos = pSrc->spr.pos;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-30 15:51:56 +00:00
|
|
|
ChangeActorSect(pActor, pSrc->sector());
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.cstat = CSTAT_SPRITE_YCENTER;
|
|
|
|
pActor->spr.shade = -12;
|
|
|
|
pActor->spr.pal = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.xvel = (RandomSize(5) - 16) << 7;
|
|
|
|
pActor->spr.yvel = (RandomSize(5) - 16) << 7;
|
|
|
|
pActor->spr.zvel = (-(RandomSize(8) + 512)) << 3;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-21 19:10:17 +00:00
|
|
|
if (bSpecial)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.xvel *= 4;
|
|
|
|
pActor->spr.yvel *= 4;
|
|
|
|
pActor->spr.zvel *= 2;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.xrepeat = 64;
|
|
|
|
pActor->spr.yrepeat = 64;
|
|
|
|
pActor->spr.xoffset = 0;
|
|
|
|
pActor->spr.yoffset = 0;
|
|
|
|
pActor->spr.picnum = nPic;
|
|
|
|
pActor->spr.lotag = runlist_HeadRun() + 1;
|
|
|
|
pActor->spr.clipdist = 40;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
// GrabTimeSlot(3);
|
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.extra = -1;
|
2022-05-23 22:30:41 +00:00
|
|
|
pActor->spr.intowner = runlist_AddRunRec(pActor->spr.lotag - 1, pActor, 0xD0000);
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.hitag = runlist_AddRunRec(NewRun, pActor, 0xD0000);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-12-23 15:44:43 +00:00
|
|
|
return pActor;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-15 19:58:07 +00:00
|
|
|
void AICreatureChunk::Tick(RunListEvent* ev)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-10-21 19:10:17 +00:00
|
|
|
auto pActor = ev->pObjActor;
|
|
|
|
if (!pActor) return;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-20 22:00:26 +00:00
|
|
|
Gravity(pActor);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-30 15:51:56 +00:00
|
|
|
auto pSector = pActor->sector();
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.pal = pSector->ceilingpal;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
auto nVal = movesprite(pActor, pActor->spr.xvel << 10, pActor->spr.yvel << 10, pActor->spr.zvel, 2560, -2560, CLIPMASK1);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2022-08-20 18:25:38 +00:00
|
|
|
if (pActor->spr.pos.Z >= pSector->floorz)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
// re-grab this variable as it may have changed in movesprite(). Note the check above is against the value *before* movesprite so don't change it.
|
2021-12-30 15:51:56 +00:00
|
|
|
pSector = pActor->sector();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.xvel = 0;
|
|
|
|
pActor->spr.yvel = 0;
|
|
|
|
pActor->spr.zvel = 0;
|
2022-08-20 14:44:30 +00:00
|
|
|
pActor->spr.pos.Z = pSector->floorz;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-10-21 18:25:15 +00:00
|
|
|
if (!nVal.type && !nVal.exbits)
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
|
2021-11-16 17:41:34 +00:00
|
|
|
int nAngle;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-21 18:25:15 +00:00
|
|
|
if (nVal.exbits & kHitAux2)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.cstat = CSTAT_SPRITE_INVISIBLE;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-10-21 18:25:15 +00:00
|
|
|
if (nVal.exbits & kHitAux1)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.xvel >>= 1;
|
|
|
|
pActor->spr.yvel >>= 1;
|
|
|
|
pActor->spr.zvel = -pActor->spr.zvel;
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-10-21 18:25:15 +00:00
|
|
|
else if (nVal.type == kHitSprite)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2022-08-16 21:17:01 +00:00
|
|
|
nAngle = nVal.actor()->int_ang();
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2021-10-21 18:25:15 +00:00
|
|
|
else if (nVal.type == kHitWall)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-11-26 13:26:03 +00:00
|
|
|
nAngle = GetWallNormal(nVal.hitWall);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// loc_16E0C
|
2021-12-23 16:04:24 +00:00
|
|
|
int nSqrt = lsqrt(((pActor->spr.yvel >> 10) * (pActor->spr.yvel >> 10)
|
|
|
|
+ (pActor->spr.xvel >> 10) * (pActor->spr.xvel >> 10)) >> 8);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.xvel = bcos(nAngle) * (nSqrt >> 1);
|
|
|
|
pActor->spr.yvel = bsin(nAngle) * (nSqrt >> 1);
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-23 22:30:41 +00:00
|
|
|
runlist_DoSubRunRec(pActor->spr.intowner);
|
2021-12-23 16:04:24 +00:00
|
|
|
runlist_FreeRun(pActor->spr.lotag - 1);
|
|
|
|
runlist_SubRunRec(pActor->spr.hitag);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-21 18:25:15 +00:00
|
|
|
ChangeActorStat(pActor, 0);
|
2021-12-23 16:04:24 +00:00
|
|
|
pActor->spr.hitag = 0;
|
|
|
|
pActor->spr.lotag = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 19:10:17 +00:00
|
|
|
DExhumedActor* UpdateEnemy(DExhumedActor** ppEnemy)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2021-10-21 19:10:17 +00:00
|
|
|
if (*ppEnemy)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-12-21 22:18:23 +00:00
|
|
|
if (!((*ppEnemy)->spr.cstat & CSTAT_SPRITE_BLOCK_ALL)) {
|
2021-10-21 19:10:17 +00:00
|
|
|
*ppEnemy = nullptr;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 19:10:17 +00:00
|
|
|
return *ppEnemy;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
2019-11-22 23:11:37 +00:00
|
|
|
END_PS_NS
|