mirror of
https://github.com/ZDoom/Raze.git
synced 2025-02-03 21:51:04 +00:00
219 lines
5.9 KiB
C++
219 lines
5.9 KiB
C++
//-------------------------------------------------------------------------
|
|
/*
|
|
Copyright (C) 1996, 2003 - 3D Realms Entertainment
|
|
Copyright (C) 2020 - Christoph Oelckers
|
|
|
|
This file is part of Raze
|
|
|
|
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
|
|
|
|
*/
|
|
//-------------------------------------------------------------------------
|
|
|
|
#include "ns.h"
|
|
#include "global.h"
|
|
#include "dukeactor.h"
|
|
#include "gamefuncs.h"
|
|
#include "models/modeldata.h"
|
|
|
|
#include "buildtiles.h"
|
|
|
|
BEGIN_DUKE_NS
|
|
|
|
void drawshadows(tspriteArray& tsprites, tspritetype* t, DDukeActor* h)
|
|
{
|
|
if (r_shadows && !(h->flags1 & SFLAG_NOSHADOW) && !(h->spr.cstat2 & CSTAT2_SPRITE_NOSHADOW))
|
|
{
|
|
auto sectp = t->sectp;
|
|
double floorz;
|
|
|
|
if ((sectp->lotag & 0xff) > 2 || h->spr.statnum == STAT_PROJECTILE || h->spr.statnum == STAT_MISC || (h->flags2 & SFLAG2_FLOATING))
|
|
floorz = sectp->floorz;
|
|
else
|
|
floorz = h->floorz;
|
|
|
|
|
|
if (h->spr.pos.Z - floorz < 8 && ps[screenpeek].GetActor()->getOffsetZ() < floorz)
|
|
{
|
|
auto shadowspr = tsprites.newTSprite();
|
|
*shadowspr = *t;
|
|
|
|
shadowspr->statnum = STAT_TEMP;
|
|
|
|
shadowspr->scale.Y = (max(t->scale.Y * 0.125, 0.0625));
|
|
shadowspr->shade = 127;
|
|
shadowspr->cstat |= CSTAT_SPRITE_TRANSLUCENT;
|
|
|
|
shadowspr->pos.Z = floorz;
|
|
shadowspr->pal = 4;
|
|
|
|
if (hw_models && modelManager.CheckModel(t->spritetexture(), t->pal))
|
|
{
|
|
shadowspr->scale.Y = (0);
|
|
// 512:trans reverse
|
|
//1024:tell MD2SPRITE.C to use Z-buffer hacks to hide overdraw issues (todo: use a stencil to do this right.)
|
|
shadowspr->clipdist |= TSPR_FLAGS_MDHACK;
|
|
shadowspr->cstat |= CSTAT_SPRITE_TRANS_FLIP;
|
|
}
|
|
else
|
|
{
|
|
// Alter the shadow's position so that it appears behind the sprite itself.
|
|
auto look = (shadowspr->pos.XY() - ps[screenpeek].GetActor()->spr.pos.XY()).Angle();
|
|
shadowspr->pos.XY() += look.ToVector() * 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
//
|
|
// some ugly stuff here: RRRA forces some animations fullbright,
|
|
// but there is no good way to set this up for CON in any decent way.
|
|
// These frames are being hacked in here. No need to make this configurable, though.
|
|
// For our new format this can be done as a real feature.
|
|
//
|
|
// ---------------------------------------------------------------------------
|
|
|
|
bool RRRAFullbrightHack(tspritetype* t, int k)
|
|
{
|
|
if (t->ownerActor->IsKindOf(RedneckBillyRayClass))
|
|
{
|
|
return k >= 102 && k <= 151;
|
|
}
|
|
else if (t->ownerActor->IsKindOf(RedneckBikerClass))
|
|
{
|
|
return (k >= 54 && k <= 58) || (k >= 84 && k <= 88);
|
|
}
|
|
else if (t->ownerActor->IsKindOf(RedneckCheerleaderClass))
|
|
{
|
|
return k >= 102 && k <= 151;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void applyanimations(tspritetype* t, DDukeActor* h, const DVector2& viewVec, DAngle viewang)
|
|
{
|
|
if (!(h->flags2 & SFLAG2_DONTANIMATE))// && (t->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_SLAB)
|
|
{
|
|
DAngle kang;
|
|
auto action = h->curAction;
|
|
int k = 0, l = 0;
|
|
if (h->curAction->name != NAME_None)
|
|
{
|
|
l = action->rotationtype;
|
|
|
|
if (tilehasmodelorvoxel(h->spr.spritetexture(), h->spr.pal))
|
|
{
|
|
k = 0;
|
|
t->cstat &= ~CSTAT_SPRITE_XFLIP;
|
|
}
|
|
else switch (l)
|
|
{
|
|
case 2:
|
|
k = angletorotation1(t->Angles.Yaw, viewang, 8, 1);
|
|
break;
|
|
|
|
case 3:
|
|
case 4:
|
|
k = angletorotation1(t->Angles.Yaw, viewang, 7);
|
|
if (k > 3)
|
|
{
|
|
t->cstat |= CSTAT_SPRITE_XFLIP;
|
|
k = 7 - k;
|
|
}
|
|
else t->cstat &= ~CSTAT_SPRITE_XFLIP;
|
|
break;
|
|
|
|
case 5:
|
|
kang = (t->pos.XY() - viewVec).Angle();
|
|
k = angletorotation1(t->Angles.Yaw, kang);
|
|
if (k > 4)
|
|
{
|
|
k = 8 - k;
|
|
t->cstat |= CSTAT_SPRITE_XFLIP;
|
|
}
|
|
else t->cstat &= ~CSTAT_SPRITE_XFLIP;
|
|
break;
|
|
case 7:
|
|
kang = (t->pos.XY() - viewVec).Angle();
|
|
k = angletorotation2(t->Angles.Yaw, kang);
|
|
if (k > 6)
|
|
{
|
|
k = 12 - k;
|
|
t->cstat |= CSTAT_SPRITE_XFLIP;
|
|
}
|
|
else t->cstat &= ~CSTAT_SPRITE_XFLIP;
|
|
break;
|
|
case 8:
|
|
k = angletorotation1(t->Angles.Yaw, viewang);
|
|
t->cstat &= ~CSTAT_SPRITE_XFLIP;
|
|
break;
|
|
default:
|
|
if (isRR())
|
|
{
|
|
bool bg = badguy(h);
|
|
if (bg && h->spr.statnum == STAT_ZOMBIEACTOR && h->spr.extra > 0)
|
|
{
|
|
kang = (t->pos.XY() - viewVec).Angle();
|
|
k = angletorotation1(t->Angles.Yaw, kang);
|
|
if (k > 4)
|
|
{
|
|
k = 8 - k;
|
|
t->cstat |= CSTAT_SPRITE_XFLIP;
|
|
}
|
|
else t->cstat &= ~CSTAT_SPRITE_XFLIP;
|
|
break;
|
|
}
|
|
k = 0;
|
|
bg = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
k += action->offset + l * h->curframe;
|
|
int texid = t->spritetexture().GetIndex() + k; // we cannot work with texture IDs here because their arithmetics are limited.
|
|
|
|
if (isRRRA() && RRRAFullbrightHack(t, k)) t->shade = -127;
|
|
|
|
FGameTexture* tex = TexMan.GameByIndex(texid);
|
|
if (l > 0)
|
|
{
|
|
while(1)
|
|
{
|
|
if (!tex || tex->isValid()) break;
|
|
texid -= l; //back up one frame if this one is invald.
|
|
tex = TexMan.GameByIndex(texid);
|
|
}
|
|
}
|
|
|
|
if (!tex)
|
|
{
|
|
t->setspritetexture(FNullTextureID());
|
|
t->scale = DVector2(0, 0);
|
|
}
|
|
else t->setspritetexture(tex->GetID());
|
|
|
|
if (h->dispictex.isValid())
|
|
h->dispictex = t->spritetexture();
|
|
}
|
|
else if (display_mirror == 1)
|
|
t->cstat |= CSTAT_SPRITE_XFLIP;
|
|
}
|
|
}
|
|
END_DUKE_NS
|