2019-09-19 22:42:45 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
|
|
|
Copyright (C) 2019 Nuke.YKT
|
|
|
|
|
|
|
|
This file is part of NBlood.
|
|
|
|
|
|
|
|
NBlood 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-09-21 18:59:54 +00:00
|
|
|
#include "ns.h" // Must come before everything else!
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
#include "build.h"
|
|
|
|
#include "blood.h"
|
2020-12-02 23:00:03 +00:00
|
|
|
#include "bloodactor.h"
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2019-09-22 06:39:22 +00:00
|
|
|
BEGIN_BLD_NS
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
CFX gFX;
|
|
|
|
|
|
|
|
struct FXDATA {
|
|
|
|
CALLBACK_ID funcID; // callback
|
2021-04-17 08:12:40 +00:00
|
|
|
uint8_t detail; // detail
|
2021-11-16 17:15:56 +00:00
|
|
|
int16_t seq; // seq
|
|
|
|
int16_t flags; // flags
|
|
|
|
int32_t gravity; // gravity
|
|
|
|
int32_t drag; // air drag
|
|
|
|
int32_t ate;
|
|
|
|
int16_t picnum; // picnum
|
2021-04-17 08:12:40 +00:00
|
|
|
uint8_t xrepeat; // xrepeat
|
|
|
|
uint8_t yrepeat; // yrepeat
|
2021-11-16 17:15:56 +00:00
|
|
|
int16_t cstat; // cstat
|
2021-04-17 08:12:40 +00:00
|
|
|
int8_t shade; // shade
|
|
|
|
uint8_t pal; // pal
|
2019-09-19 22:42:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
FXDATA gFXData[] = {
|
2019-10-11 21:59:39 +00:00
|
|
|
{ kCallbackNone, 0, 49, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 0, 50, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 0, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 0, 52, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 0, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 0, 44, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 0, 45, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 0, 46, 1, -128, 8192, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 2, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 2, 42, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 2, 43, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 48, 3, -256, 8192, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 60, 3, -256, 8192, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackFXBloodBits, 2, 0, 1, 46603, 2048, 480, 2154, 40, 40, 0, -12, 0 },
|
|
|
|
{ kCallbackNone, 2, 0, 3, 46603, 5120, 480, 2269, 24, 24, 0, -128, 0 },
|
|
|
|
{ kCallbackNone, 2, 0, 3, 46603, 5120, 480, 1720, 24, 24, 0, -128, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 1, 58254, 3072, 480, 2280, 48, 48, 0, -128, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 1, 58254, 3072, 480, 3135, 48, 48, 0, -128, 0 },
|
|
|
|
{ kCallbackNone, 0, 0, 3, 58254, 1024, 480, 3261, 32, 32, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 3, 58254, 1024, 480, 3265, 32, 32, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 3, 58254, 1024, 480, 3269, 32, 32, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 3, 58254, 1024, 480, 3273, 32, 32, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 3, 58254, 1024, 480, 3277, 32, 32, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 2, 0, 1, -27962, 8192, 600, 1128, 16, 16, 514, -16, 0 }, // bubble 1
|
|
|
|
{ kCallbackNone, 2, 0, 1, -18641, 8192, 600, 1128, 12, 12, 514, -16, 0 }, // bubble 2
|
|
|
|
{ kCallbackNone, 2, 0, 1, -9320, 8192, 600, 1128, 8, 8, 514, -16, 0 }, // bubble 3
|
|
|
|
{ kCallbackNone, 2, 0, 1, -18641, 8192, 600, 1131, 32, 32, 514, -16, 0 },
|
|
|
|
{ kCallbackFXBloodBits, 2, 0, 3, 27962, 4096, 480, 733, 32, 32, 0, -16, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 3, 18641, 4096, 120, 2261, 12, 12, 0, -128, 0 },
|
|
|
|
{ kCallbackNone, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 3, 58254, 3328, 480, 2185, 48, 48, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 0, 0, 3, 58254, 1024, 480, 2620, 48, 48, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 55, 1, -13981, 5120, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 56, 1, -13981, 5120, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 57, 1, 0, 2048, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 58, 1, 0, 2048, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 2, 0, 0, 0, 0, 960, 956, 32, 32, 610, 0, 0 },
|
|
|
|
{ kCallbackFXBouncingSleeve, 2, 62, 0, 46603, 1024, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackFXBouncingSleeve, 2, 63, 0, 46603, 1024, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackFXBouncingSleeve, 2, 64, 0, 46603, 1024, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackFXBouncingSleeve, 2, 65, 0, 46603, 1024, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackFXBouncingSleeve, 2, 66, 0, 46603, 1024, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackFXBouncingSleeve, 2, 67, 0, 46603, 1024, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 3, 0, 0, 0, 838, 16, 16, 80, -8, 0 },
|
|
|
|
{ kCallbackNone, 0, 0, 3, 34952, 8192, 0, 2078, 64, 64, 0, -8, 0 },
|
|
|
|
{ kCallbackNone, 0, 0, 3, 34952, 8192, 0, 1106, 64, 64, 0, -8, 0 },
|
|
|
|
{ kCallbackNone, 0, 0, 3, 58254, 3328, 480, 2406, 48, 48, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 3, 46603, 4096, 480, 3511, 64, 64, 0, -128, 0 },
|
|
|
|
{ kCallbackNone, 0, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 2, 11, 3, -256, 8192, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 2, 11, 3, 0, 8192, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ kCallbackNone, 1, 30, 3, 0, 0, 0, 0, 40, 40, 80, -8, 0 },
|
|
|
|
{ kCallbackFXPodBloodSplat, 2, 0, 3, 27962, 4096, 480, 4023, 32, 32, 0, -16, 0 },
|
|
|
|
{ kCallbackFXPodBloodSplat, 2, 0, 3, 27962, 4096, 480, 4028, 32, 32, 0, -16, 0 },
|
|
|
|
{ kCallbackNone, 2, 0, 0, 0, 0, 480, 926, 32, 32, 610, -12, 0 },
|
|
|
|
{ kCallbackNone, 1, 70, 1, -13981, 5120, 0, 0, 0, 0, 0, 0, 0 }
|
2019-09-19 22:42:45 +00:00
|
|
|
};
|
|
|
|
|
2021-08-26 22:07:33 +00:00
|
|
|
void CFX::destroy(DBloodActor* actor)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
if (!actor) return;
|
2021-08-27 07:44:47 +00:00
|
|
|
evKillActor(actor);
|
2021-08-26 22:07:33 +00:00
|
|
|
if (actor->hasX()) seqKill(actor);
|
|
|
|
DeleteSprite(actor);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
|
2021-08-26 22:07:33 +00:00
|
|
|
void CFX::remove(DBloodActor* actor)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
if (!actor) return;
|
|
|
|
spritetype *pSprite = &actor->s();
|
|
|
|
if (actor->hasX()) seqKill(actor);
|
2019-09-19 22:42:45 +00:00
|
|
|
if (pSprite->statnum != kStatFree)
|
2021-08-26 22:07:33 +00:00
|
|
|
actPostSprite(actor, kStatFree);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
|
2021-09-01 19:56:39 +00:00
|
|
|
DBloodActor* CFX::fxSpawnActor(FX_ID nFx, int nSector, int x, int y, int z, unsigned int a6)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
if (nSector < 0 || nSector >= numsectors)
|
2021-08-26 22:07:33 +00:00
|
|
|
return nullptr;
|
2019-09-19 22:42:45 +00:00
|
|
|
int nSector2 = nSector;
|
|
|
|
if (!FindSector(x, y, z, &nSector2))
|
2021-08-26 22:07:33 +00:00
|
|
|
return nullptr;
|
2020-01-21 20:51:05 +00:00
|
|
|
if (adult_lockout && gGameOptions.nGameType <= 0)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
switch (nFx)
|
|
|
|
{
|
|
|
|
case FX_0:
|
|
|
|
case FX_1:
|
|
|
|
case FX_2:
|
|
|
|
case FX_3:
|
|
|
|
case FX_13:
|
|
|
|
case FX_34:
|
|
|
|
case FX_35:
|
|
|
|
case FX_36:
|
2021-08-26 22:07:33 +00:00
|
|
|
return nullptr;
|
2019-09-19 22:42:45 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nFx < 0 || nFx >= kFXMax)
|
2021-08-26 22:07:33 +00:00
|
|
|
return nullptr;
|
2019-09-19 22:42:45 +00:00
|
|
|
FXDATA *pFX = &gFXData[nFx];
|
|
|
|
if (gStatCount[1] == 512)
|
|
|
|
{
|
2021-09-01 19:56:39 +00:00
|
|
|
BloodStatIterator it(kStatFX);
|
|
|
|
auto iactor = it.Next();
|
|
|
|
while (iactor && (iactor->s().flags & 32))
|
|
|
|
iactor = it.Next();
|
|
|
|
if (!iactor)
|
2021-08-26 22:07:33 +00:00
|
|
|
return nullptr;
|
|
|
|
destroy(iactor);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
2021-11-23 23:55:57 +00:00
|
|
|
auto actor = actSpawnSprite(§or[nSector], x, y, z, 1, 0);
|
2020-12-05 16:24:27 +00:00
|
|
|
spritetype* pSprite = &actor->s();
|
2019-09-19 22:42:45 +00:00
|
|
|
pSprite->type = nFx;
|
2021-04-17 08:12:40 +00:00
|
|
|
pSprite->picnum = pFX->picnum;
|
|
|
|
pSprite->cstat |= pFX->cstat;
|
|
|
|
pSprite->shade = pFX->shade;
|
|
|
|
pSprite->pal = pFX->pal;
|
2021-09-04 17:44:19 +00:00
|
|
|
pSprite->detail = pFX->detail;
|
2021-04-17 08:12:40 +00:00
|
|
|
if (pFX->xrepeat > 0)
|
|
|
|
pSprite->xrepeat = pFX->xrepeat;
|
|
|
|
if (pFX->yrepeat > 0)
|
|
|
|
pSprite->yrepeat = pFX->yrepeat;
|
|
|
|
if ((pFX->flags & 1) && Chance(0x8000))
|
2019-09-19 22:42:45 +00:00
|
|
|
pSprite->cstat |= 4;
|
2021-04-17 08:12:40 +00:00
|
|
|
if ((pFX->flags & 2) && Chance(0x8000))
|
2019-09-19 22:42:45 +00:00
|
|
|
pSprite->cstat |= 8;
|
2021-04-17 08:12:40 +00:00
|
|
|
if (pFX->seq)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2021-08-27 20:13:17 +00:00
|
|
|
actor->addX();
|
|
|
|
seqSpawn(pFX->seq, actor, -1);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
if (a6 == 0)
|
|
|
|
a6 = pFX->ate;
|
|
|
|
if (a6)
|
2021-08-27 07:44:47 +00:00
|
|
|
evPostActor(actor, a6+Random2(a6>>1), kCallbackRemove);
|
2021-09-01 19:56:39 +00:00
|
|
|
return actor;
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CFX::fxProcess(void)
|
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
BloodStatIterator it(kStatFX);
|
|
|
|
while (auto actor = it.Next())
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
spritetype *pSprite = &actor->s();
|
|
|
|
viewBackupSpriteLoc(actor);
|
2021-11-06 14:53:16 +00:00
|
|
|
int nSector = pSprite->sectnum;
|
2021-11-09 08:06:54 +00:00
|
|
|
assert(validSectorIndex(nSector));
|
2020-10-11 10:38:17 +00:00
|
|
|
assert(pSprite->type < kFXMax);
|
2019-09-19 22:42:45 +00:00
|
|
|
FXDATA *pFXData = &gFXData[pSprite->type];
|
2021-09-04 10:47:34 +00:00
|
|
|
actAirDrag(actor, pFXData->drag);
|
2021-09-04 10:52:02 +00:00
|
|
|
pSprite->x += actor->xvel>>12;
|
|
|
|
pSprite->y += actor->yvel>>12;
|
|
|
|
pSprite->z += actor->zvel>>8;
|
2019-09-19 22:42:45 +00:00
|
|
|
// Weird...
|
2021-11-19 19:35:33 +00:00
|
|
|
if (actor->xvel || (actor->yvel && pSprite->z >= pSprite->sector()->floorz))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
updatesector(pSprite->x, pSprite->y, &nSector);
|
|
|
|
if (nSector == -1)
|
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
remove(actor);
|
2019-09-19 22:42:45 +00:00
|
|
|
continue;
|
|
|
|
}
|
2021-11-23 23:38:07 +00:00
|
|
|
if (getflorzofslopeptr(pSprite->sector(), pSprite->x, pSprite->y) <= pSprite->z)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
if (pFXData->funcID < 0 || pFXData->funcID >= kCallbackMax)
|
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
remove(actor);
|
2019-09-19 22:42:45 +00:00
|
|
|
continue;
|
|
|
|
}
|
2021-08-26 22:07:33 +00:00
|
|
|
assert(gCallback[pFXData->funcID] != nullptr);
|
|
|
|
gCallback[pFXData->funcID](actor, 0);
|
2019-09-19 22:42:45 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (nSector != pSprite->sectnum)
|
|
|
|
{
|
2021-11-09 08:06:54 +00:00
|
|
|
assert(validSectorIndex(nSector));
|
2021-08-27 14:38:53 +00:00
|
|
|
ChangeActorSect(actor, nSector);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
}
|
2021-09-04 10:52:02 +00:00
|
|
|
if (actor->xvel || actor->yvel || actor->zvel)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
int32_t floorZ, ceilZ;
|
|
|
|
getzsofslope(nSector, pSprite->x, pSprite->y, &ceilZ, &floorZ);
|
|
|
|
if (ceilZ > pSprite->z && !(sector[nSector].ceilingstat&1))
|
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
remove(actor);
|
2019-09-19 22:42:45 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (floorZ < pSprite->z)
|
|
|
|
{
|
|
|
|
if (pFXData->funcID < 0 || pFXData->funcID >= kCallbackMax)
|
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
remove(actor);
|
2019-09-19 22:42:45 +00:00
|
|
|
continue;
|
|
|
|
}
|
2021-08-26 22:07:33 +00:00
|
|
|
assert(gCallback[pFXData->funcID] != nullptr);
|
|
|
|
gCallback[pFXData->funcID](actor, 0);
|
2019-09-19 22:42:45 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2021-09-04 10:52:02 +00:00
|
|
|
actor->zvel += pFXData->gravity;
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-26 22:07:33 +00:00
|
|
|
void fxSpawnBlood(DBloodActor *actor, int )
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
spritetype* pSprite = &actor->s();
|
2019-09-19 22:42:45 +00:00
|
|
|
if (pSprite->sectnum < 0 || pSprite->sectnum >= numsectors)
|
|
|
|
return;
|
|
|
|
int nSector = pSprite->sectnum;
|
|
|
|
if (!FindSector(pSprite->x, pSprite->y, pSprite->z, &nSector))
|
|
|
|
return;
|
2020-01-21 20:51:05 +00:00
|
|
|
if (adult_lockout && gGameOptions.nGameType <= 0)
|
2019-09-19 22:42:45 +00:00
|
|
|
return;
|
2021-11-23 23:41:19 +00:00
|
|
|
auto bloodactor = gFX.fxSpawnActor(FX_27, pSprite->sector(), pSprite->x, pSprite->y, pSprite->z, 0);
|
2021-08-31 23:46:42 +00:00
|
|
|
if (bloodactor)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2021-08-31 23:46:42 +00:00
|
|
|
bloodactor->s().ang = 1024;
|
2021-09-04 10:52:02 +00:00
|
|
|
bloodactor->xvel = Random2(0x6aaaa);
|
|
|
|
bloodactor->yvel = Random2(0x6aaaa);
|
|
|
|
bloodactor->zvel = -(int)Random(0x10aaaa)-100;
|
2021-08-27 07:44:47 +00:00
|
|
|
evPostActor(bloodactor, 8, kCallbackFXBloodSpurt);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-26 22:07:33 +00:00
|
|
|
void fxSpawnPodStuff(DBloodActor* actor, int )
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
auto pSprite = &actor->s();
|
2019-09-19 22:42:45 +00:00
|
|
|
if (pSprite->sectnum < 0 || pSprite->sectnum >= numsectors)
|
|
|
|
return;
|
|
|
|
int nSector = pSprite->sectnum;
|
|
|
|
if (!FindSector(pSprite->x, pSprite->y, pSprite->z, &nSector))
|
|
|
|
return;
|
2020-01-21 20:51:05 +00:00
|
|
|
if (adult_lockout && gGameOptions.nGameType <= 0)
|
2019-09-19 22:42:45 +00:00
|
|
|
return;
|
2021-08-31 23:46:42 +00:00
|
|
|
DBloodActor *spawnactor;
|
2019-10-11 21:59:39 +00:00
|
|
|
if (pSprite->type == kDudePodGreen)
|
2021-11-23 23:41:19 +00:00
|
|
|
spawnactor = gFX.fxSpawnActor(FX_53, pSprite->sector(), pSprite->x, pSprite->y, pSprite->z, 0);
|
2019-09-19 22:42:45 +00:00
|
|
|
else
|
2021-11-23 23:41:19 +00:00
|
|
|
spawnactor = gFX.fxSpawnActor(FX_54, pSprite->sector(), pSprite->x, pSprite->y, pSprite->z, 0);
|
2021-08-31 23:46:42 +00:00
|
|
|
if (spawnactor)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2021-08-31 23:46:42 +00:00
|
|
|
spawnactor->s().ang = 1024;
|
2021-09-04 10:52:02 +00:00
|
|
|
spawnactor->xvel = Random2(0x6aaaa);
|
|
|
|
spawnactor->yvel = Random2(0x6aaaa);
|
|
|
|
spawnactor->zvel = -(int)Random(0x10aaaa)-100;
|
2021-08-27 07:44:47 +00:00
|
|
|
evPostActor(spawnactor, 8, kCallbackFXPodBloodSpray);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-26 22:07:33 +00:00
|
|
|
void fxSpawnEjectingBrass(DBloodActor* actor, int z, int a3, int a4)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
auto pSprite = &actor->s();
|
2021-09-02 19:37:28 +00:00
|
|
|
int x = pSprite->x + MulScale(pSprite->clipdist - 4, Cos(pSprite->ang), 28);
|
|
|
|
int y = pSprite->y + MulScale(pSprite->clipdist - 4, Sin(pSprite->ang), 28);
|
|
|
|
x += MulScale(a3, Cos(pSprite->ang + 512), 30);
|
|
|
|
y += MulScale(a3, Sin(pSprite->ang + 512), 30);
|
2021-11-23 23:41:19 +00:00
|
|
|
auto pBrass = gFX.fxSpawnActor((FX_ID)(FX_37 + Random(3)), pSprite->sector(), x, y, z, 0);
|
2019-10-26 07:08:45 +00:00
|
|
|
if (pBrass)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2019-10-26 07:08:45 +00:00
|
|
|
if (!VanillaMode())
|
2021-08-31 23:46:42 +00:00
|
|
|
pBrass->s().ang = Random(2047);
|
2021-09-02 19:37:28 +00:00
|
|
|
int nDist = (a4 << 18) / 120 + Random2(((a4 / 4) << 18) / 120);
|
|
|
|
int nAngle = pSprite->ang + Random2(56) + 512;
|
2021-09-04 10:52:02 +00:00
|
|
|
pBrass->xvel = MulScale(nDist, Cos(nAngle), 30);
|
|
|
|
pBrass->yvel = MulScale(nDist, Sin(nAngle), 30);
|
|
|
|
pBrass->zvel = actor->zvel - (0x20000 + (Random2(40) << 18) / 120);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-26 22:07:33 +00:00
|
|
|
void fxSpawnEjectingShell(DBloodActor* actor, int z, int a3, int a4)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2021-08-26 22:07:33 +00:00
|
|
|
auto pSprite = &actor->s();
|
2021-09-02 19:37:28 +00:00
|
|
|
int x = pSprite->x + MulScale(pSprite->clipdist - 4, Cos(pSprite->ang), 28);
|
|
|
|
int y = pSprite->y + MulScale(pSprite->clipdist - 4, Sin(pSprite->ang), 28);
|
|
|
|
x += MulScale(a3, Cos(pSprite->ang + 512), 30);
|
|
|
|
y += MulScale(a3, Sin(pSprite->ang + 512), 30);
|
2021-11-23 23:41:19 +00:00
|
|
|
auto pShell = gFX.fxSpawnActor((FX_ID)(FX_40 + Random(3)), pSprite->sector(), x, y, z, 0);
|
2019-09-19 22:42:45 +00:00
|
|
|
if (pShell)
|
|
|
|
{
|
2019-10-26 07:08:45 +00:00
|
|
|
if (!VanillaMode())
|
2021-08-31 23:46:42 +00:00
|
|
|
pShell->s().ang = Random(2047);
|
2021-09-02 19:37:28 +00:00
|
|
|
int nDist = (a4 << 18) / 120 + Random2(((a4 / 4) << 18) / 120);
|
|
|
|
int nAngle = pSprite->ang + Random2(56) + 512;
|
2021-09-04 10:52:02 +00:00
|
|
|
pShell->xvel = MulScale(nDist, Cos(nAngle), 30);
|
|
|
|
pShell->yvel = MulScale(nDist, Sin(nAngle), 30);
|
|
|
|
pShell->zvel = actor->zvel - (0x20000 + (Random2(20) << 18) / 120);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-22 06:39:22 +00:00
|
|
|
|
2021-04-11 10:42:59 +00:00
|
|
|
void fxPrecache()
|
2020-01-02 11:01:18 +00:00
|
|
|
{
|
|
|
|
for (int i = 0; i < kFXMax; i++)
|
|
|
|
{
|
2021-04-17 08:12:40 +00:00
|
|
|
tilePrecacheTile(gFXData[i].picnum, 0, 0);
|
|
|
|
if (gFXData[i].seq)
|
|
|
|
seqPrecacheId(gFXData[i].seq, 0);
|
2020-01-02 11:01:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-22 06:39:22 +00:00
|
|
|
END_BLD_NS
|