2006-04-13 20:47:06 +00:00
|
|
|
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
2021-03-24 18:45:42 +00:00
|
|
|
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
2006-04-13 20:47:06 +00:00
|
|
|
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
|
|
|
// See the included license file "BUILDLIC.TXT" for license info.
|
|
|
|
//
|
|
|
|
// This file has been modified from Ken Silverman's original release
|
2012-03-12 04:47:04 +00:00
|
|
|
// by Jonathon Fowler (jf@jonof.id.au)
|
2018-11-05 07:28:01 +00:00
|
|
|
// by the EDuke32 team (development@voidpoint.com)
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:09:48 +00:00
|
|
|
#define engine_c_
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-03-29 12:01:46 +00:00
|
|
|
#include "gl_load.h"
|
2006-04-13 20:47:06 +00:00
|
|
|
#include "build.h"
|
2020-09-06 10:44:58 +00:00
|
|
|
#include "automap.h"
|
2019-12-17 22:25:07 +00:00
|
|
|
|
2020-01-28 09:31:59 +00:00
|
|
|
#include "imagehelpers.h"
|
2018-11-18 18:09:48 +00:00
|
|
|
#include "palette.h"
|
2019-10-23 16:36:48 +00:00
|
|
|
#include "gamecvars.h"
|
2019-11-06 22:40:10 +00:00
|
|
|
#include "c_console.h"
|
|
|
|
#include "v_2ddrawer.h"
|
2019-11-08 22:02:52 +00:00
|
|
|
#include "v_draw.h"
|
2019-11-10 09:01:31 +00:00
|
|
|
#include "stats.h"
|
2020-10-04 16:31:48 +00:00
|
|
|
#include "razemenu.h"
|
2019-12-26 13:04:53 +00:00
|
|
|
#include "version.h"
|
2020-05-25 15:11:32 +00:00
|
|
|
#include "earcut.hpp"
|
2020-08-12 20:52:41 +00:00
|
|
|
#include "gamestate.h"
|
2020-08-28 07:06:49 +00:00
|
|
|
#include "inputstate.h"
|
|
|
|
#include "printf.h"
|
2020-11-10 21:07:45 +00:00
|
|
|
#include "gamecontrol.h"
|
2021-03-15 22:46:03 +00:00
|
|
|
#include "render.h"
|
2021-03-18 09:19:13 +00:00
|
|
|
#include "gamefuncs.h"
|
2021-04-05 11:55:36 +00:00
|
|
|
#include "hw_voxels.h"
|
2021-12-03 19:20:33 +00:00
|
|
|
#include "coreactor.h"
|
2018-11-18 18:09:48 +00:00
|
|
|
|
2011-03-04 08:50:58 +00:00
|
|
|
#ifdef USE_OPENGL
|
2011-10-02 07:18:17 +00:00
|
|
|
# include "mdsprite.h"
|
2019-12-23 18:37:40 +00:00
|
|
|
#include "v_video.h"
|
2020-03-29 12:01:46 +00:00
|
|
|
#include "gl_renderer.h"
|
2008-05-10 01:29:37 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-01-28 21:41:07 +00:00
|
|
|
int32_t mdtims, omdtims;
|
2020-01-28 21:54:57 +00:00
|
|
|
|
2018-02-15 03:49:23 +00:00
|
|
|
uint8_t globalr = 255, globalg = 255, globalb = 255;
|
|
|
|
|
2019-06-25 11:29:42 +00:00
|
|
|
static int16_t radarang[1280];
|
2012-11-05 02:49:08 +00:00
|
|
|
|
2020-07-14 15:35:19 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
//
|
|
|
|
// Internal Engine Functions
|
|
|
|
//
|
|
|
|
|
2022-01-08 11:23:05 +00:00
|
|
|
void engineInit(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2022-01-08 11:23:05 +00:00
|
|
|
int32_t i;
|
|
|
|
|
|
|
|
for (i=0; i<=512; i++)
|
|
|
|
sintable[i] = int(sin(i * BAngRadian) * +SINTABLEUNIT);
|
|
|
|
for (i=513; i<1024; i++)
|
|
|
|
sintable[i] = sintable[1024-i];
|
|
|
|
for (i=1024; i<2048; i++)
|
|
|
|
sintable[i] = -sintable[i-1024];
|
|
|
|
|
|
|
|
for (i=0; i<640; i++)
|
|
|
|
radarang[i] = atan((639.5 - i) / 160.) * (-64. / BAngRadian);
|
|
|
|
for (i=0; i<640; i++)
|
|
|
|
radarang[1279-i] = -radarang[i];
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// lintersect (internal)
|
|
|
|
//
|
2019-04-05 17:45:16 +00:00
|
|
|
int32_t lintersect(const int32_t originX, const int32_t originY, const int32_t originZ,
|
|
|
|
const int32_t destX, const int32_t destY, const int32_t destZ,
|
|
|
|
const int32_t lineStartX, const int32_t lineStartY, const int32_t lineEndX, const int32_t lineEndY,
|
|
|
|
int32_t *intersectionX, int32_t *intersectionY, int32_t *intersectionZ)
|
2007-12-12 17:42:14 +00:00
|
|
|
{
|
2019-04-05 17:45:16 +00:00
|
|
|
const vec2_t ray = { destX-originX,
|
|
|
|
destY-originY };
|
|
|
|
const vec2_t lineVec = { lineEndX-lineStartX,
|
|
|
|
lineEndY-lineStartY };
|
|
|
|
const vec2_t originDiff = { lineStartX-originX,
|
|
|
|
lineStartY-originY };
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2021-12-22 09:28:51 +00:00
|
|
|
const int32_t rayCrossLineVec = ray.X*lineVec.Y - ray.Y*lineVec.X;
|
|
|
|
const int32_t originDiffCrossRay = originDiff.X*ray.Y - originDiff.Y*ray.X;
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2019-04-05 17:45:16 +00:00
|
|
|
if (rayCrossLineVec == 0)
|
2018-05-15 16:45:34 +00:00
|
|
|
{
|
2019-09-22 19:26:07 +00:00
|
|
|
if (originDiffCrossRay != 0 || enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
|
2019-04-05 17:45:16 +00:00
|
|
|
{
|
|
|
|
// line segments are parallel
|
|
|
|
return 0;
|
|
|
|
}
|
2018-12-15 01:40:31 +00:00
|
|
|
|
2019-04-05 17:45:16 +00:00
|
|
|
// line segments are collinear
|
2021-12-22 09:28:51 +00:00
|
|
|
const int32_t rayLengthSquared = ray.X*ray.X + ray.Y*ray.Y;
|
|
|
|
const int32_t rayDotOriginDiff = ray.X*originDiff.X + ray.Y*originDiff.Y;
|
|
|
|
const int32_t rayDotLineEndDiff = rayDotOriginDiff + ray.X*lineVec.X + ray.Y*lineVec.Y;
|
2019-04-05 17:45:19 +00:00
|
|
|
int64_t t = min(rayDotOriginDiff, rayDotLineEndDiff);
|
2019-04-05 17:45:16 +00:00
|
|
|
if (rayDotOriginDiff < 0)
|
|
|
|
{
|
|
|
|
if (rayDotLineEndDiff < 0)
|
|
|
|
return 0;
|
2018-12-15 01:40:31 +00:00
|
|
|
|
2019-04-05 17:45:16 +00:00
|
|
|
t = 0;
|
|
|
|
}
|
|
|
|
else if (rayDotOriginDiff > rayLengthSquared)
|
|
|
|
{
|
|
|
|
if (rayDotLineEndDiff > rayLengthSquared)
|
|
|
|
return 0;
|
2018-12-15 01:40:31 +00:00
|
|
|
|
2019-04-05 17:45:16 +00:00
|
|
|
t = rayDotLineEndDiff;
|
|
|
|
}
|
2020-07-14 18:21:16 +00:00
|
|
|
t = (t << 24) / rayLengthSquared;
|
2019-04-05 17:45:19 +00:00
|
|
|
|
2021-12-22 09:26:51 +00:00
|
|
|
*intersectionX = originX + MulScale(ray.X, t, 24);
|
2021-12-22 09:28:51 +00:00
|
|
|
*intersectionY = originY + MulScale(ray.Y, t, 24);
|
2021-01-04 11:36:54 +00:00
|
|
|
*intersectionZ = originZ + MulScale(destZ-originZ, t, 24);
|
2018-12-15 01:40:31 +00:00
|
|
|
|
2019-04-05 17:45:16 +00:00
|
|
|
return 1;
|
2018-05-15 16:45:34 +00:00
|
|
|
}
|
2018-12-15 01:40:31 +00:00
|
|
|
|
2021-12-22 09:28:51 +00:00
|
|
|
const int32_t originDiffCrossLineVec = originDiff.X*lineVec.Y - originDiff.Y*lineVec.X;
|
2019-04-05 17:45:16 +00:00
|
|
|
static const int32_t signBit = 1u<<31u;
|
2019-04-05 17:45:19 +00:00
|
|
|
// Any point on either line can be expressed as p+t*r and q+u*s
|
|
|
|
// The two line segments intersect when we can find a t & u such that p+t*r = q+u*s
|
|
|
|
// If the point is outside of the bounds of the line segment, we know we don't have an intersection.
|
2019-04-05 17:45:16 +00:00
|
|
|
// t is < 0 if (originDiffCrossLineVec^rayCrossLineVec) & signBit)
|
|
|
|
// u is < 0 if (originDiffCrossRay^rayCrossLineVec) & signBit
|
2021-01-04 12:02:00 +00:00
|
|
|
// t is > 1 if abs(originDiffCrossLineVec) > abs(rayCrossLineVec)
|
|
|
|
// u is > 1 if abs(originDiffCrossRay) > abs(rayCrossLineVec)
|
2019-04-05 17:45:19 +00:00
|
|
|
// where int32_t u = tabledivide64(((int64_t) originDiffCrossRay) << 24L, rayCrossLineVec);
|
|
|
|
if (((originDiffCrossLineVec^rayCrossLineVec) & signBit) ||
|
|
|
|
((originDiffCrossRay^rayCrossLineVec) & signBit) ||
|
2021-01-04 12:02:00 +00:00
|
|
|
abs(originDiffCrossLineVec) > abs(rayCrossLineVec) ||
|
|
|
|
abs(originDiffCrossRay) > abs(rayCrossLineVec))
|
2019-04-05 17:45:16 +00:00
|
|
|
{
|
|
|
|
// line segments do not overlap
|
|
|
|
return 0;
|
|
|
|
}
|
2019-04-05 17:45:19 +00:00
|
|
|
|
2020-07-14 18:21:16 +00:00
|
|
|
int64_t t = (int64_t(originDiffCrossLineVec) << 24) / rayCrossLineVec;
|
2019-04-05 17:45:19 +00:00
|
|
|
// For sake of completeness/readability, alternative to the above approach for an early out & avoidance of an extra division:
|
|
|
|
|
2021-12-22 09:26:51 +00:00
|
|
|
*intersectionX = originX + MulScale(ray.X, t, 24);
|
2021-12-22 09:28:51 +00:00
|
|
|
*intersectionY = originY + MulScale(ray.Y, t, 24);
|
2021-01-04 11:36:54 +00:00
|
|
|
*intersectionZ = originZ + MulScale(destZ-originZ, t, 24);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2015-01-11 04:56:58 +00:00
|
|
|
return 1;
|
2010-09-27 21:52:04 +00:00
|
|
|
}
|
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
//
|
|
|
|
// rintersect (internal)
|
|
|
|
//
|
2021-07-04 11:05:33 +00:00
|
|
|
// returns: -1 if didn't intersect, coefficient (x3--x4 fraction)<<16 else
|
2016-06-21 00:33:30 +00:00
|
|
|
int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
|
2019-06-25 11:28:40 +00:00
|
|
|
int32_t vx, int32_t vy, int32_t vz,
|
2016-06-21 00:33:30 +00:00
|
|
|
int32_t x3, int32_t y3, int32_t x4, int32_t y4,
|
|
|
|
int32_t *intx, int32_t *inty, int32_t *intz)
|
2007-12-12 17:42:14 +00:00
|
|
|
{
|
|
|
|
//p1 towards p2 is a ray
|
2012-06-13 23:13:39 +00:00
|
|
|
|
2019-06-25 11:28:40 +00:00
|
|
|
int64_t const x34=x3-x4, y34=y3-y4;
|
|
|
|
int64_t const x31=x3-x1, y31=y3-y1;
|
|
|
|
|
|
|
|
int64_t const bot = vx*y34 - vy*x34;
|
|
|
|
int64_t const topt = x31*y34 - y31*x34;
|
2013-03-24 18:55:40 +00:00
|
|
|
|
|
|
|
if (bot == 0)
|
|
|
|
return -1;
|
2012-06-13 23:13:39 +00:00
|
|
|
|
2019-06-25 11:28:40 +00:00
|
|
|
int64_t const topu = vx*y31 - vy*x31;
|
|
|
|
|
|
|
|
if (bot > 0 && (topt < 0 || topu < 0 || topu >= bot))
|
|
|
|
return -1;
|
|
|
|
else if (bot < 0 && (topt > 0 || topu > 0 || topu <= bot))
|
|
|
|
return -1;
|
|
|
|
|
2020-09-13 18:15:46 +00:00
|
|
|
int64_t t = (topt << 16) / bot;
|
|
|
|
*intx = x1 + ((vx*t) >> 16);
|
|
|
|
*inty = y1 + ((vy*t) >> 16);
|
|
|
|
*intz = z1 + ((vz*t) >> 16);
|
2012-06-13 23:13:39 +00:00
|
|
|
|
2020-09-13 18:15:46 +00:00
|
|
|
t = (topu << 16) / bot;
|
2019-06-25 11:28:40 +00:00
|
|
|
|
2020-08-30 21:34:40 +00:00
|
|
|
assert((unsigned)t < 65536);
|
2012-10-14 20:41:34 +00:00
|
|
|
|
|
|
|
return t;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-02-05 14:32:15 +00:00
|
|
|
int32_t _getangle(int32_t xvect, int32_t yvect)
|
2012-09-02 14:12:01 +00:00
|
|
|
{
|
2015-01-11 04:56:58 +00:00
|
|
|
int32_t rv;
|
|
|
|
|
|
|
|
if ((xvect | yvect) == 0)
|
|
|
|
rv = 0;
|
|
|
|
else if (xvect == 0)
|
|
|
|
rv = 512 + ((yvect < 0) << 10);
|
|
|
|
else if (yvect == 0)
|
|
|
|
rv = ((xvect < 0) << 10);
|
|
|
|
else if (xvect == yvect)
|
|
|
|
rv = 256 + ((xvect < 0) << 10);
|
|
|
|
else if (xvect == -yvect)
|
|
|
|
rv = 768 + ((xvect > 0) << 10);
|
2021-01-04 12:02:00 +00:00
|
|
|
else if (abs(xvect) > abs(yvect))
|
2021-01-04 12:34:55 +00:00
|
|
|
rv = ((radarang[640 + Scale(160, yvect, xvect)] >> 6) + ((xvect < 0) << 10)) & 2047;
|
|
|
|
else rv = ((radarang[640 - Scale(160, xvect, yvect)] >> 6) + 512 + ((yvect < 0) << 10)) & 2047;
|
2015-01-11 04:56:58 +00:00
|
|
|
|
|
|
|
return rv;
|
2012-09-02 14:12:01 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-04-17 13:21:22 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// cansee
|
|
|
|
//
|
2019-09-22 19:26:07 +00:00
|
|
|
|
2021-12-05 21:01:02 +00:00
|
|
|
int cansee(int x1, int y1, int z1, sectortype* sect1, int x2, int y2, int z2, sectortype* sect2)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2021-12-05 21:01:02 +00:00
|
|
|
if (!sect1 || !sect2) return false;
|
|
|
|
|
2012-11-17 19:46:47 +00:00
|
|
|
const int32_t x21 = x2-x1, y21 = y2-y1, z21 = z2-z1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-11-17 19:46:47 +00:00
|
|
|
if (x1 == x2 && y1 == y2)
|
|
|
|
return (sect1 == sect2);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2021-12-05 21:01:02 +00:00
|
|
|
BFSSectorSearch search(sect1);
|
2011-07-01 17:15:07 +00:00
|
|
|
|
2021-12-05 21:01:02 +00:00
|
|
|
while (auto sec = search.GetNext())
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2021-12-30 10:38:34 +00:00
|
|
|
const walltype* wal;
|
2021-12-14 09:15:58 +00:00
|
|
|
int cnt;
|
2021-12-30 10:38:34 +00:00
|
|
|
for (cnt=sec->wallnum,wal=sec->firstWall(); cnt>0; cnt--,wal++)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2021-12-30 10:38:34 +00:00
|
|
|
auto const wal2 = wal->point2Wall();
|
2022-01-27 16:41:10 +00:00
|
|
|
const int32_t x31 = wal->wall_int_pos().X-x1, x34 = wal->wall_int_pos().X-wal2->wall_int_pos().X;
|
|
|
|
const int32_t y31 = wal->wall_int_pos().Y-y1, y34 = wal->wall_int_pos().Y-wal2->wall_int_pos().Y;
|
2012-11-17 19:46:47 +00:00
|
|
|
|
2021-12-05 21:01:02 +00:00
|
|
|
int32_t x, y, z, t, bot;
|
2012-11-17 19:46:47 +00:00
|
|
|
int32_t cfz[2];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
bot = y21*x34-x21*y34; if (bot <= 0) continue;
|
2012-06-13 23:13:39 +00:00
|
|
|
// XXX: OVERFLOW
|
2006-04-13 20:47:06 +00:00
|
|
|
t = y21*x31-x21*y31; if ((unsigned)t >= (unsigned)bot) continue;
|
2011-07-01 17:15:07 +00:00
|
|
|
t = y31*x34-x31*y34;
|
|
|
|
if ((unsigned)t >= (unsigned)bot)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2011-07-01 17:15:07 +00:00
|
|
|
|
2021-12-18 14:16:31 +00:00
|
|
|
if (!wal->twoSided() || wal->cstat & CSTAT_WALL_1WAY)
|
2021-12-05 21:01:02 +00:00
|
|
|
return 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2021-01-04 11:51:41 +00:00
|
|
|
t = DivScale(t,bot, 24);
|
2021-01-04 11:36:54 +00:00
|
|
|
x = x1 + MulScale(x21,t, 24);
|
|
|
|
y = y1 + MulScale(y21,t, 24);
|
|
|
|
z = z1 + MulScale(z21,t, 24);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2021-12-05 21:01:02 +00:00
|
|
|
getzsofslopeptr(sec, x,y, &cfz[0],&cfz[1]);
|
2011-07-01 17:15:07 +00:00
|
|
|
|
2013-04-12 11:59:22 +00:00
|
|
|
if (z <= cfz[0] || z >= cfz[1])
|
2011-07-01 17:15:07 +00:00
|
|
|
{
|
2013-04-15 10:48:09 +00:00
|
|
|
return 0;
|
2011-07-01 17:15:07 +00:00
|
|
|
}
|
|
|
|
|
2021-12-05 21:01:02 +00:00
|
|
|
auto nexts = wal->nextSector();
|
|
|
|
getzsofslopeptr(nexts, x,y, &cfz[0],&cfz[1]);
|
2013-04-15 10:48:09 +00:00
|
|
|
if (z <= cfz[0] || z >= cfz[1])
|
|
|
|
return 0;
|
2011-07-01 17:15:07 +00:00
|
|
|
|
2021-11-18 00:20:46 +00:00
|
|
|
search.Add(nexts);
|
2011-07-01 17:15:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2021-11-18 00:20:46 +00:00
|
|
|
return search.Check(sect2);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// neartag
|
|
|
|
//
|
2012-11-17 19:46:47 +00:00
|
|
|
|
2021-12-03 23:38:11 +00:00
|
|
|
void neartag(const vec3_t& sv, sectortype* sect, int ange, HitInfoBase& result, int neartagrange, int tagsearch)
|
|
|
|
{
|
2021-01-04 11:36:54 +00:00
|
|
|
const int32_t vx = MulScale(bcos(ange), neartagrange, 14);
|
|
|
|
const int32_t vy = MulScale(bsin(ange), neartagrange, 14);
|
2021-12-22 09:40:26 +00:00
|
|
|
vec3_t hitv = { sv.X+vx, sv.Y+vy, 0 };
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2021-12-03 23:38:11 +00:00
|
|
|
result.clearObj();
|
2022-08-17 16:53:45 +00:00
|
|
|
result.hitpos.X = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2021-12-03 23:38:11 +00:00
|
|
|
if (!sect || (tagsearch & 3) == 0)
|
2012-11-17 19:46:47 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2021-12-03 23:38:11 +00:00
|
|
|
BFSSectorSearch search(sect);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2021-12-03 23:38:11 +00:00
|
|
|
while (auto dasect = search.GetNext())
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2021-12-03 23:38:11 +00:00
|
|
|
for (auto& w : wallsofsector(dasect))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2021-12-03 23:38:11 +00:00
|
|
|
auto wal = &w;
|
2021-12-30 10:38:34 +00:00
|
|
|
auto const wal2 = wal->point2Wall();
|
2021-12-03 23:38:11 +00:00
|
|
|
const auto nextsect = wal->nextSector();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2022-01-27 16:41:10 +00:00
|
|
|
const int32_t x1 = wal->wall_int_pos().X, y1 = wal->wall_int_pos().Y, x2 = wal2->wall_int_pos().X, y2 = wal2->wall_int_pos().Y;
|
2012-11-17 19:46:47 +00:00
|
|
|
int32_t intx, inty, intz, good = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2021-12-03 23:38:11 +00:00
|
|
|
if (wal->twoSided())
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2021-12-03 23:38:11 +00:00
|
|
|
if ((tagsearch & 1) && nextsect->lotag) good |= 1;
|
|
|
|
if ((tagsearch & 2) && nextsect->hitag) good |= 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2012-11-17 19:46:47 +00:00
|
|
|
|
2021-12-03 23:38:11 +00:00
|
|
|
if ((tagsearch & 1) && wal->lotag) good |= 2;
|
|
|
|
if ((tagsearch & 2) && wal->hitag) good |= 2;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2021-12-03 23:38:11 +00:00
|
|
|
if ((good == 0) && (!wal->twoSided())) continue;
|
2021-12-22 09:40:26 +00:00
|
|
|
if ((coord_t)(x1 - sv.X) * (y2 - sv.Y) < (coord_t)(x2 - sv.X) * (y1 - sv.Y)) continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2021-12-22 09:41:47 +00:00
|
|
|
if (lintersect(sv.X, sv.Y, sv.Z, hitv.X, hitv.Y, hitv.Z, x1, y1, x2, y2, &intx, &inty, &intz) == 1)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
|
|
|
if (good != 0)
|
|
|
|
{
|
2021-12-03 23:38:11 +00:00
|
|
|
if (good & 1) result.hitSector = nextsect;
|
|
|
|
if (good & 2) result.hitWall = wal;
|
2022-08-17 16:53:45 +00:00
|
|
|
result.hitpos.X = DMulScale(intx - sv.X, bcos(ange), inty - sv.Y, bsin(ange), 14) * inttoworld;
|
2021-12-22 09:41:47 +00:00
|
|
|
hitv.X = intx; hitv.Y = inty; hitv.Z = intz;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2012-11-17 19:46:47 +00:00
|
|
|
|
2021-12-03 23:38:11 +00:00
|
|
|
if (wal->twoSided())
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2021-12-03 23:38:11 +00:00
|
|
|
search.Add(nextsect);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-17 19:46:47 +00:00
|
|
|
if (tagsearch & 4)
|
|
|
|
continue; // skip sprite search
|
2011-03-04 08:50:58 +00:00
|
|
|
|
2021-12-03 23:38:11 +00:00
|
|
|
TSectIterator<DCoreActor> it(dasect);
|
|
|
|
while (auto actor = it.Next())
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2021-12-22 22:14:16 +00:00
|
|
|
if (actor->spr.cstat2 & CSTAT2_SPRITE_NOFIND)
|
2021-04-17 07:37:38 +00:00
|
|
|
continue;
|
2012-02-20 19:54:24 +00:00
|
|
|
|
2021-12-22 22:14:16 +00:00
|
|
|
if (((tagsearch&1) && actor->spr.lotag) || ((tagsearch&2) && actor->spr.hitag))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2021-12-30 10:28:09 +00:00
|
|
|
if (try_facespr_intersect(actor, sv, vx, vy, 0, &hitv, 1))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2021-12-03 23:38:11 +00:00
|
|
|
result.hitActor = actor;
|
2022-08-17 16:53:45 +00:00
|
|
|
result.hitpos.X = DMulScale(hitv.X-sv.X, bcos(ange), hitv.Y-sv.Y, bsin(ange), 14) * inttoworld;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-12-12 17:42:14 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-29 23:14:45 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
//
|
|
|
|
// rotatepoint
|
|
|
|
//
|
2019-04-18 17:24:10 +00:00
|
|
|
void rotatepoint(vec2_t const pivot, vec2_t p, int16_t const daang, vec2_t * const p2)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2020-11-14 09:00:37 +00:00
|
|
|
int const dacos = bcos(daang);
|
|
|
|
int const dasin = bsin(daang);
|
2021-12-22 09:26:51 +00:00
|
|
|
p.X -= pivot.X;
|
2021-12-22 09:28:51 +00:00
|
|
|
p.Y -= pivot.Y;
|
|
|
|
p2->X = DMulScale(p.X, dacos, -p.Y, dasin, 14) + pivot.X;
|
|
|
|
p2->Y = DMulScale(p.Y, dacos, p.X, dasin, 14) + pivot.Y;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2021-04-05 11:55:36 +00:00
|
|
|
int tilehasmodelorvoxel(int const tilenume, int pal)
|
|
|
|
{
|
|
|
|
return
|
|
|
|
(mdinited && hw_models && tile2model[Ptile2tile(tilenume, pal)].modelid != -1) ||
|
|
|
|
(r_voxels && tiletovox[tilenume] != -1);
|
|
|
|
}
|