mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
6df435c8c5
32 changed files with 297 additions and 241 deletions
|
@ -865,13 +865,13 @@ public:
|
|||
// more precise, but slower version, being used in a few places
|
||||
fixed_t Distance2D(AActor *other, bool absolute = false)
|
||||
{
|
||||
return xs_RoundToInt(FVector2(X() - other->X(), Y() - other->Y()).Length());
|
||||
return xs_RoundToInt(TVector2<double>(X() - other->X(), Y() - other->Y()).Length());
|
||||
}
|
||||
|
||||
// a full 3D version of the above
|
||||
fixed_t Distance3D(AActor *other, bool absolute = false)
|
||||
{
|
||||
return xs_RoundToInt(FVector3(X() - other->X(), Y() - other->Y(), Z() - other->Z()).Length());
|
||||
return xs_RoundToInt(TVector3<double>(X() - other->X(), Y() - other->Y(), Z() - other->Z()).Length());
|
||||
}
|
||||
|
||||
angle_t AngleTo(AActor *other, bool absolute = false) const
|
||||
|
|
|
@ -2512,8 +2512,8 @@ void AM_rotate(fixed_t *xp, fixed_t *yp, angle_t a)
|
|||
cosrot = cos(rot);
|
||||
}
|
||||
|
||||
double x = FIXED2FLOAT(*xp);
|
||||
double y = FIXED2FLOAT(*yp);
|
||||
double x = FIXED2DBL(*xp);
|
||||
double y = FIXED2DBL(*yp);
|
||||
double tmpx = (x * cosrot) - (y * sinrot);
|
||||
y = (x * sinrot) + (y * cosrot);
|
||||
x = tmpx;
|
||||
|
|
|
@ -1084,7 +1084,7 @@ CCMD(currentpos)
|
|||
if(mo)
|
||||
{
|
||||
Printf("Current player position: (%1.3f,%1.3f,%1.3f), angle: %1.3f, floorheight: %1.3f, sector:%d, lightlevel: %d\n",
|
||||
FIXED2FLOAT(mo->X()), FIXED2FLOAT(mo->Y()), FIXED2FLOAT(mo->Z()), mo->angle/float(ANGLE_1), FIXED2FLOAT(mo->floorz), mo->Sector->sectornum, mo->Sector->lightlevel);
|
||||
FIXED2DBL(mo->X()), FIXED2DBL(mo->Y()), FIXED2DBL(mo->Z()), ANGLE2DBL(mo->angle), FIXED2DBL(mo->floorz), mo->Sector->sectornum, mo->Sector->lightlevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2481,8 +2481,9 @@ void D_DoomMain (void)
|
|||
FinishDehPatch();
|
||||
|
||||
InitActorNumsFromMapinfo();
|
||||
PClassActor::StaticSetActorNums ();
|
||||
InitSpawnablesFromMapinfo();
|
||||
PClassActor::StaticSetActorNums();
|
||||
|
||||
//Added by MC:
|
||||
bglobal.getspawned.Clear();
|
||||
argcount = Args->CheckParmList("-bots", &args);
|
||||
|
|
|
@ -95,11 +95,11 @@ void DMover::Serialize (FArchive &arc)
|
|||
arc << interpolation;
|
||||
}
|
||||
|
||||
void DMover::StopInterpolation()
|
||||
void DMover::StopInterpolation(bool force)
|
||||
{
|
||||
if (interpolation != NULL)
|
||||
{
|
||||
interpolation->DelRef();
|
||||
interpolation->DelRef(force);
|
||||
interpolation = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ protected:
|
|||
DMover ();
|
||||
void Serialize (FArchive &arc);
|
||||
void Destroy();
|
||||
void StopInterpolation();
|
||||
void StopInterpolation(bool force = false);
|
||||
inline EResult MoveFloor (fixed_t speed, fixed_t dest, int crush, int direction, bool hexencrush)
|
||||
{
|
||||
return MovePlane (speed, dest, crush, 0, direction, hexencrush);
|
||||
|
|
|
@ -1571,7 +1571,7 @@ public:
|
|||
bool res = DMover::crushed != MoveFloor(speed, dest, crush, direction, false);
|
||||
Destroy();
|
||||
m_Sector->floordata=NULL;
|
||||
StopInterpolation();
|
||||
StopInterpolation(true);
|
||||
m_Sector=NULL;
|
||||
return res;
|
||||
}
|
||||
|
@ -1656,6 +1656,14 @@ public:
|
|||
m_Speed=movespeed;
|
||||
m_Direction = _m_Direction;
|
||||
m_FloorDestDist = moveheight;
|
||||
|
||||
// Do not interpolate instant movement floors.
|
||||
fixed_t movedist = abs(-sec->floorplane.d - moveheight);
|
||||
if (m_Speed >= movedist)
|
||||
{
|
||||
StopInterpolation(true);
|
||||
}
|
||||
|
||||
StartFloorSound();
|
||||
}
|
||||
};
|
||||
|
@ -1713,7 +1721,7 @@ public:
|
|||
bool res = DMover::crushed != MoveCeiling(speed, dest, crush, direction, false);
|
||||
Destroy();
|
||||
m_Sector->ceilingdata=NULL;
|
||||
StopInterpolation ();
|
||||
StopInterpolation (true);
|
||||
m_Sector=NULL;
|
||||
return res;
|
||||
}
|
||||
|
@ -1806,7 +1814,7 @@ public:
|
|||
fixed_t movedist = abs(sec->ceilingplane.d - m_BottomHeight);
|
||||
if (m_Speed >= movedist)
|
||||
{
|
||||
StopInterpolation ();
|
||||
StopInterpolation (true);
|
||||
m_Silent=2;
|
||||
}
|
||||
PlayCeilingSound();
|
||||
|
@ -3817,19 +3825,12 @@ void FParser::SF_ObjType()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
inline fixed_t double2fixed(double t)
|
||||
{
|
||||
return (fixed_t)(t*65536.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FParser::SF_Sin()
|
||||
{
|
||||
if (CheckArgs(1))
|
||||
{
|
||||
t_return.type = svt_fixed;
|
||||
t_return.value.f = double2fixed(sin(floatvalue(t_argv[0])));
|
||||
t_return.value.f = FLOAT2FIXED(sin(floatvalue(t_argv[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3839,7 +3840,7 @@ void FParser::SF_ASin()
|
|||
if (CheckArgs(1))
|
||||
{
|
||||
t_return.type = svt_fixed;
|
||||
t_return.value.f = double2fixed(asin(floatvalue(t_argv[0])));
|
||||
t_return.value.f = FLOAT2FIXED(asin(floatvalue(t_argv[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3849,7 +3850,7 @@ void FParser::SF_Cos()
|
|||
if (CheckArgs(1))
|
||||
{
|
||||
t_return.type = svt_fixed;
|
||||
t_return.value.f = double2fixed(cos(floatvalue(t_argv[0])));
|
||||
t_return.value.f = FLOAT2FIXED(cos(floatvalue(t_argv[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3859,7 +3860,7 @@ void FParser::SF_ACos()
|
|||
if (CheckArgs(1))
|
||||
{
|
||||
t_return.type = svt_fixed;
|
||||
t_return.value.f = double2fixed(acos(floatvalue(t_argv[0])));
|
||||
t_return.value.f = FLOAT2FIXED(acos(floatvalue(t_argv[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3869,7 +3870,7 @@ void FParser::SF_Tan()
|
|||
if (CheckArgs(1))
|
||||
{
|
||||
t_return.type = svt_fixed;
|
||||
t_return.value.f = double2fixed(tan(floatvalue(t_argv[0])));
|
||||
t_return.value.f = FLOAT2FIXED(tan(floatvalue(t_argv[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3879,7 +3880,7 @@ void FParser::SF_ATan()
|
|||
if (CheckArgs(1))
|
||||
{
|
||||
t_return.type = svt_fixed;
|
||||
t_return.value.f = double2fixed(atan(floatvalue(t_argv[0])));
|
||||
t_return.value.f = FLOAT2FIXED(atan(floatvalue(t_argv[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3889,7 +3890,7 @@ void FParser::SF_Exp()
|
|||
if (CheckArgs(1))
|
||||
{
|
||||
t_return.type = svt_fixed;
|
||||
t_return.value.f = double2fixed(exp(floatvalue(t_argv[0])));
|
||||
t_return.value.f = FLOAT2FIXED(exp(floatvalue(t_argv[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3898,7 +3899,7 @@ void FParser::SF_Log()
|
|||
if (CheckArgs(1))
|
||||
{
|
||||
t_return.type = svt_fixed;
|
||||
t_return.value.f = double2fixed(log(floatvalue(t_argv[0])));
|
||||
t_return.value.f = FLOAT2FIXED(log(floatvalue(t_argv[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3908,7 +3909,7 @@ void FParser::SF_Sqrt()
|
|||
if (CheckArgs(1))
|
||||
{
|
||||
t_return.type = svt_fixed;
|
||||
t_return.value.f = double2fixed(sqrt(floatvalue(t_argv[0])));
|
||||
t_return.value.f = FLOAT2FIXED(sqrt(floatvalue(t_argv[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3928,7 +3929,7 @@ void FParser::SF_Pow()
|
|||
if (CheckArgs(2))
|
||||
{
|
||||
t_return.type = svt_fixed;
|
||||
t_return.value.f = double2fixed(pow(floatvalue(t_argv[0]), floatvalue(t_argv[1])));
|
||||
t_return.value.f = FLOAT2FIXED(pow(floatvalue(t_argv[0]), floatvalue(t_argv[1])));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -165,8 +165,8 @@ public:
|
|||
void Activate (AActor *activator);
|
||||
void Deactivate (AActor *activator);
|
||||
protected:
|
||||
float Splerp (float p1, float p2, float p3, float p4);
|
||||
float Lerp (float p1, float p2);
|
||||
double Splerp (double p1, double p2, double p3, double p4);
|
||||
double Lerp (double p1, double p2);
|
||||
virtual bool Interpolate ();
|
||||
virtual void NewNode ();
|
||||
|
||||
|
@ -191,10 +191,10 @@ void APathFollower::Serialize (FArchive &arc)
|
|||
|
||||
// Interpolate between p2 and p3 along a Catmull-Rom spline
|
||||
// http://research.microsoft.com/~hollasch/cgindex/curves/catmull-rom.html
|
||||
float APathFollower::Splerp (float p1, float p2, float p3, float p4)
|
||||
double APathFollower::Splerp (double p1, double p2, double p3, double p4)
|
||||
{
|
||||
float t = Time;
|
||||
float res = 2*p2;
|
||||
double t = Time;
|
||||
double res = 2*p2;
|
||||
res += (p3 - p1) * Time;
|
||||
t *= Time;
|
||||
res += (2*p1 - 5*p2 + 4*p3 - p4) * t;
|
||||
|
@ -204,7 +204,7 @@ float APathFollower::Splerp (float p1, float p2, float p3, float p4)
|
|||
}
|
||||
|
||||
// Linearly interpolate between p1 and p2
|
||||
float APathFollower::Lerp (float p1, float p2)
|
||||
double APathFollower::Lerp (double p1, double p2)
|
||||
{
|
||||
return p1 + Time * (p2 - p1);
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ void APathFollower::Tick ()
|
|||
|
||||
if (Interpolate ())
|
||||
{
|
||||
Time += 8.f / ((float)CurrNode->args[1] * (float)TICRATE);
|
||||
Time += float(8.f / ((double)CurrNode->args[1] * (double)TICRATE));
|
||||
if (Time > 1.f)
|
||||
{
|
||||
Time -= 1.f;
|
||||
|
@ -371,20 +371,20 @@ bool APathFollower::Interpolate ()
|
|||
fixed_t x, y, z;
|
||||
if (args[2] & 1)
|
||||
{ // linear
|
||||
x = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->X()), FIXED2FLOAT(CurrNode->Next->X())));
|
||||
y = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->Y()), FIXED2FLOAT(CurrNode->Next->Y())));
|
||||
z = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->Z()), FIXED2FLOAT(CurrNode->Next->Z())));
|
||||
x = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->X()), FIXED2DBL(CurrNode->Next->X())));
|
||||
y = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->Y()), FIXED2DBL(CurrNode->Next->Y())));
|
||||
z = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->Z()), FIXED2DBL(CurrNode->Next->Z())));
|
||||
}
|
||||
else
|
||||
{ // spline
|
||||
if (CurrNode->Next->Next==NULL) return false;
|
||||
|
||||
x = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->X()), FIXED2FLOAT(CurrNode->X()),
|
||||
FIXED2FLOAT(CurrNode->Next->X()), FIXED2FLOAT(CurrNode->Next->Next->X())));
|
||||
y = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->Y()), FIXED2FLOAT(CurrNode->Y()),
|
||||
FIXED2FLOAT(CurrNode->Next->Y()), FIXED2FLOAT(CurrNode->Next->Next->Y())));
|
||||
z = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->Z()), FIXED2FLOAT(CurrNode->Z()),
|
||||
FIXED2FLOAT(CurrNode->Next->Z()), FIXED2FLOAT(CurrNode->Next->Next->Z())));
|
||||
x = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->X()), FIXED2DBL(CurrNode->X()),
|
||||
FIXED2DBL(CurrNode->Next->X()), FIXED2DBL(CurrNode->Next->Next->X())));
|
||||
y = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->Y()), FIXED2DBL(CurrNode->Y()),
|
||||
FIXED2DBL(CurrNode->Next->Y()), FIXED2DBL(CurrNode->Next->Next->Y())));
|
||||
z = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->Z()), FIXED2DBL(CurrNode->Z()),
|
||||
FIXED2DBL(CurrNode->Next->Z()), FIXED2DBL(CurrNode->Next->Next->Z())));
|
||||
}
|
||||
SetXYZ(x, y, z);
|
||||
LinkToWorld ();
|
||||
|
@ -442,11 +442,11 @@ bool APathFollower::Interpolate ()
|
|||
{
|
||||
if (args[2] & 2)
|
||||
{ // interpolate angle
|
||||
float angle1 = (float)CurrNode->angle;
|
||||
float angle2 = (float)CurrNode->Next->angle;
|
||||
double angle1 = (double)CurrNode->angle;
|
||||
double angle2 = (double)CurrNode->Next->angle;
|
||||
if (angle2 - angle1 <= -2147483648.f)
|
||||
{
|
||||
float lerped = Lerp (angle1, angle2 + 4294967296.f);
|
||||
double lerped = Lerp (angle1, angle2 + 4294967296.f);
|
||||
if (lerped >= 4294967296.f)
|
||||
{
|
||||
angle = xs_CRoundToUInt(lerped - 4294967296.f);
|
||||
|
@ -458,7 +458,7 @@ bool APathFollower::Interpolate ()
|
|||
}
|
||||
else if (angle2 - angle1 >= 2147483648.f)
|
||||
{
|
||||
float lerped = Lerp (angle1, angle2 - 4294967296.f);
|
||||
double lerped = Lerp (angle1, angle2 - 4294967296.f);
|
||||
if (lerped < 0.f)
|
||||
{
|
||||
angle = xs_CRoundToUInt(lerped + 4294967296.f);
|
||||
|
@ -477,15 +477,15 @@ bool APathFollower::Interpolate ()
|
|||
{ // linear
|
||||
if (args[2] & 4)
|
||||
{ // interpolate pitch
|
||||
pitch = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->pitch), FIXED2FLOAT(CurrNode->Next->pitch)));
|
||||
pitch = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->pitch), FIXED2DBL(CurrNode->Next->pitch)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // spline
|
||||
if (args[2] & 4)
|
||||
{ // interpolate pitch
|
||||
pitch = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->pitch), FIXED2FLOAT(CurrNode->pitch),
|
||||
FIXED2FLOAT(CurrNode->Next->pitch), FIXED2FLOAT(CurrNode->Next->Next->pitch)));
|
||||
pitch = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->pitch), FIXED2DBL(CurrNode->pitch),
|
||||
FIXED2DBL(CurrNode->Next->pitch), FIXED2DBL(CurrNode->Next->Next->pitch)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -310,8 +310,8 @@ class CommandDrawImage : public SBarInfoCommandFlowControl
|
|||
|
||||
if (applyscale)
|
||||
{
|
||||
spawnScaleX = FIXED2FLOAT(item->scaleX);
|
||||
spawnScaleY = FIXED2FLOAT(item->scaleY);
|
||||
spawnScaleX = FIXED2DBL(item->scaleX);
|
||||
spawnScaleY = FIXED2DBL(item->scaleY);
|
||||
}
|
||||
|
||||
texture = TexMan[icon];
|
||||
|
|
|
@ -7782,8 +7782,12 @@ scriptwait:
|
|||
break;
|
||||
|
||||
case PRINTNAME_LEVEL:
|
||||
work += level.MapName;
|
||||
break;
|
||||
{
|
||||
FString uppername = level.MapName;
|
||||
uppername.ToUpper();
|
||||
work += uppername;
|
||||
break;
|
||||
}
|
||||
|
||||
case PRINTNAME_SKILL:
|
||||
work += G_SkillName();
|
||||
|
|
|
@ -804,7 +804,7 @@ static void CreateStartSpot (fixed_t *pos, FMapThing *start)
|
|||
|
||||
static void CalcPlane (SlopeWork &slope, secplane_t &plane)
|
||||
{
|
||||
FVector3 pt[3];
|
||||
TVector3<double> pt[3];
|
||||
long j;
|
||||
|
||||
slope.x[0] = slope.wal->x; slope.y[0] = slope.wal->y;
|
||||
|
@ -823,8 +823,8 @@ static void CalcPlane (SlopeWork &slope, secplane_t &plane)
|
|||
-slope.dy, slope.x[2]-slope.wal->x);
|
||||
slope.z[2] += Scale (slope.heinum, j, slope.i);
|
||||
|
||||
pt[0] = FVector3(slope.dx, -slope.dy, 0);
|
||||
pt[1] = FVector3(slope.x[2] - slope.x[0], slope.y[0] - slope.y[2], (slope.z[2] - slope.z[0]) / 16);
|
||||
pt[0] = TVector3<double>(slope.dx, -slope.dy, 0);
|
||||
pt[1] = TVector3<double>(slope.x[2] - slope.x[0], slope.y[0] - slope.y[2], (slope.z[2] - slope.z[0]) / 16);
|
||||
pt[2] = (pt[0] ^ pt[1]).Unit();
|
||||
|
||||
if ((pt[2][2] < 0 && plane.c > 0) || (pt[2][2] > 0 && plane.c < 0))
|
||||
|
@ -832,10 +832,10 @@ static void CalcPlane (SlopeWork &slope, secplane_t &plane)
|
|||
pt[2] = -pt[2];
|
||||
}
|
||||
|
||||
plane.a = fixed_t(pt[2][0]*65536.f);
|
||||
plane.b = fixed_t(pt[2][1]*65536.f);
|
||||
plane.c = fixed_t(pt[2][2]*65536.f);
|
||||
plane.ic = fixed_t(65536.f/pt[2][2]);
|
||||
plane.a = FLOAT2FIXED(pt[2][0]);
|
||||
plane.b = FLOAT2FIXED(pt[2][1]);
|
||||
plane.c = FLOAT2FIXED(pt[2][2]);
|
||||
plane.ic = DivScale32(1, plane.c);
|
||||
plane.d = -TMulScale8
|
||||
(plane.a, slope.x[0]<<4, plane.b, (-slope.y[0])<<4, plane.c, slope.z[0]);
|
||||
}
|
||||
|
|
|
@ -412,7 +412,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line,
|
|||
}
|
||||
if (ceiling->m_Speed >= movedist)
|
||||
{
|
||||
ceiling->StopInterpolation();
|
||||
ceiling->StopInterpolation(true);
|
||||
}
|
||||
|
||||
// set texture/type change properties
|
||||
|
|
110
src/p_enemy.cpp
110
src/p_enemy.cpp
|
@ -1792,7 +1792,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look)
|
|||
}
|
||||
else
|
||||
{
|
||||
CALL_ACTION(A_Wander, self);
|
||||
A_Wander(self);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1952,7 +1952,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx)
|
|||
}
|
||||
else
|
||||
{
|
||||
CALL_ACTION(A_Wander, self);
|
||||
A_Wander(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2051,50 +2051,74 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClearLastHeard)
|
|||
// A_Wander
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Wander)
|
||||
enum ChaseFlags
|
||||
{
|
||||
CHF_FASTCHASE = 1,
|
||||
CHF_NOPLAYACTIVE = 2,
|
||||
CHF_NIGHTMAREFAST = 4,
|
||||
CHF_RESURRECT = 8,
|
||||
CHF_DONTMOVE = 16,
|
||||
CHF_NORANDOMTURN = 32,
|
||||
CHF_NODIRECTIONTURN = 64,
|
||||
CHF_NOPOSTATTACKTURN = 128,
|
||||
CHF_STOPIFBLOCKED = 256,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Wander)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT_OPT(flags) { flags = 0; }
|
||||
A_Wander(self, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// [MC] I had to move this out from within A_Wander in order to allow flags to
|
||||
// pass into it. That meant replacing the CALL_ACTION(A_Wander) functions with
|
||||
// just straight up defining A_Wander in order to compile. Looking around though,
|
||||
// actors from the games themselves just do a straight A_Chase call itself so
|
||||
// I saw no harm in it.
|
||||
|
||||
void A_Wander(AActor *self, int flags)
|
||||
{
|
||||
// [RH] Strife probably clears this flag somewhere, but I couldn't find where.
|
||||
// This seems as good a place as any.
|
||||
self->flags4 &= ~MF4_INCOMBAT;
|
||||
|
||||
if (self->flags5 & MF5_INCONVERSATION)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (self->flags4 & MF4_STANDSTILL)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (self->reactiontime != 0)
|
||||
{
|
||||
self->reactiontime--;
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// turn towards movement direction if not there yet
|
||||
if (self->movedir < DI_NODIR)
|
||||
if (!(flags & CHF_NODIRECTIONTURN) && (self->movedir < DI_NODIR))
|
||||
{
|
||||
self->angle &= (angle_t)(7<<29);
|
||||
self->angle &= (angle_t)(7 << 29);
|
||||
int delta = self->angle - (self->movedir << 29);
|
||||
if (delta > 0)
|
||||
{
|
||||
self->angle -= ANG90/2;
|
||||
self->angle -= ANG90 / 2;
|
||||
}
|
||||
else if (delta < 0)
|
||||
{
|
||||
self->angle += ANG90/2;
|
||||
self->angle += ANG90 / 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (--self->movecount < 0 || !P_Move (self))
|
||||
if ((--self->movecount < 0 && !(flags & CHF_NORANDOMTURN)) || (!P_Move(self) && !(flags & CHF_STOPIFBLOCKED)))
|
||||
{
|
||||
P_RandomChaseDir (self);
|
||||
P_RandomChaseDir(self);
|
||||
self->movecount += 5;
|
||||
}
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_Look2
|
||||
|
@ -2165,8 +2189,8 @@ nosee:
|
|||
//
|
||||
//=============================================================================
|
||||
#define CLASS_BOSS_STRAFE_RANGE 64*10*FRACUNIT
|
||||
|
||||
void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove)
|
||||
|
||||
void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove, int flags)
|
||||
{
|
||||
int delta;
|
||||
|
||||
|
@ -2228,7 +2252,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
|
|||
{
|
||||
A_FaceTarget(actor);
|
||||
}
|
||||
else if (actor->movedir < 8)
|
||||
else if (!(flags & CHF_NODIRECTIONTURN) && actor->movedir < 8)
|
||||
{
|
||||
actor->angle &= (angle_t)(7<<29);
|
||||
delta = actor->angle - (actor->movedir << 29);
|
||||
|
@ -2300,7 +2324,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
|
|||
//CALL_ACTION(A_Look, actor);
|
||||
if (actor->target == NULL)
|
||||
{
|
||||
if (!dontmove) CALL_ACTION(A_Wander, actor);
|
||||
if (!dontmove) A_Wander(actor);
|
||||
actor->flags &= ~MF_INCHASE;
|
||||
return;
|
||||
}
|
||||
|
@ -2318,10 +2342,15 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
|
|||
if (actor->flags & MF_JUSTATTACKED)
|
||||
{
|
||||
actor->flags &= ~MF_JUSTATTACKED;
|
||||
if (!actor->isFast() && !dontmove)
|
||||
if (!actor->isFast() && !dontmove && !(flags & CHF_NOPOSTATTACKTURN) && !(flags & CHF_STOPIFBLOCKED))
|
||||
{
|
||||
P_NewChaseDir (actor);
|
||||
}
|
||||
//Because P_TryWalk would never be reached if the actor is stopped by a blocking object,
|
||||
//need to make sure the movecount is reset, otherwise they will just keep attacking
|
||||
//over and over again.
|
||||
if (flags & CHF_STOPIFBLOCKED)
|
||||
actor->movecount = pr_trywalk() & 15;
|
||||
actor->flags &= ~MF_INCHASE;
|
||||
return;
|
||||
}
|
||||
|
@ -2478,7 +2507,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
|
|||
|
||||
if (actor->strafecount)
|
||||
actor->strafecount--;
|
||||
|
||||
|
||||
// class bosses don't do this when strafing
|
||||
if ((!fastchase || !actor->FastChaseStrafeCount) && !dontmove)
|
||||
{
|
||||
|
@ -2488,16 +2517,15 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
|
|||
FTextureID oldFloor = actor->floorpic;
|
||||
|
||||
// chase towards player
|
||||
if (--actor->movecount < 0 || !P_Move (actor))
|
||||
if ((--actor->movecount < 0 && !(flags & CHF_NORANDOMTURN)) || (!P_Move(actor) && !(flags & CHF_STOPIFBLOCKED)))
|
||||
{
|
||||
P_NewChaseDir (actor);
|
||||
P_NewChaseDir(actor);
|
||||
}
|
||||
|
||||
// if the move was illegal, reset it
|
||||
// (copied from A_SerpentChase - it applies to everything with CANTLEAVEFLOORPIC!)
|
||||
if (actor->flags2&MF2_CANTLEAVEFLOORPIC && actor->floorpic != oldFloor )
|
||||
{
|
||||
if (P_TryMove (actor, oldX, oldY, false))
|
||||
if (P_TryMove(actor, oldX, oldY, false))
|
||||
{
|
||||
if (nomonsterinterpolation)
|
||||
{
|
||||
|
@ -2505,7 +2533,8 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
|
|||
actor->PrevY = oldY;
|
||||
}
|
||||
}
|
||||
P_NewChaseDir (actor);
|
||||
if (!(flags & CHF_STOPIFBLOCKED))
|
||||
P_NewChaseDir(actor);
|
||||
}
|
||||
}
|
||||
else if (dontmove && actor->movecount > 0) actor->movecount--;
|
||||
|
@ -2666,15 +2695,6 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
enum ChaseFlags
|
||||
{
|
||||
CHF_FASTCHASE = 1,
|
||||
CHF_NOPLAYACTIVE = 2,
|
||||
CHF_NIGHTMAREFAST = 4,
|
||||
CHF_RESURRECT = 8,
|
||||
CHF_DONTMOVE = 16,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Chase)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
@ -2686,22 +2706,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Chase)
|
|||
{
|
||||
if ((flags & CHF_RESURRECT) && P_CheckForResurrection(self, false))
|
||||
return 0;
|
||||
|
||||
|
||||
A_DoChase(stack, self, !!(flags&CHF_FASTCHASE), melee, missile, !(flags&CHF_NOPLAYACTIVE),
|
||||
!!(flags&CHF_NIGHTMAREFAST), !!(flags&CHF_DONTMOVE));
|
||||
!!(flags&CHF_NIGHTMAREFAST), !!(flags&CHF_DONTMOVE), flags);
|
||||
}
|
||||
else // this is the old default A_Chase
|
||||
{
|
||||
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false);
|
||||
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, flags);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FastChase)
|
||||
{
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
A_DoChase(stack, self, true, self->MeleeState, self->MissileState, true, true, false);
|
||||
return 0;
|
||||
A_DoChase(stack, self, true, self->MeleeState, self->MissileState, true, true, false, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_VileChase)
|
||||
|
@ -2709,9 +2729,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_VileChase)
|
|||
PARAM_ACTION_PROLOGUE;
|
||||
if (!P_CheckForResurrection(self, true))
|
||||
{
|
||||
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false);
|
||||
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0);
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase)
|
||||
|
@ -2725,14 +2745,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase)
|
|||
// Now that A_Chase can handle state label parameters, this function has become rather useless...
|
||||
A_DoChase(stack, self, false,
|
||||
domelee ? self->MeleeState : NULL, domissile ? self->MissileState : NULL,
|
||||
playactive, nightmarefast, false);
|
||||
playactive, nightmarefast, false, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// for internal use
|
||||
void A_Chase(VMFrameStack *stack, AActor *self)
|
||||
{
|
||||
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false);
|
||||
{
|
||||
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
@ -61,7 +61,6 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis
|
|||
void A_Unblock(AActor *self, bool drop);
|
||||
|
||||
DECLARE_ACTION(A_Look)
|
||||
DECLARE_ACTION(A_Wander)
|
||||
DECLARE_ACTION(A_BossDeath)
|
||||
DECLARE_ACTION(A_Pain)
|
||||
DECLARE_ACTION(A_MonsterRail)
|
||||
|
@ -70,10 +69,11 @@ DECLARE_ACTION(A_Scream)
|
|||
DECLARE_ACTION(A_FreezeDeath)
|
||||
DECLARE_ACTION(A_FreezeDeathChunks)
|
||||
void A_BossDeath(AActor *self);
|
||||
|
||||
|
||||
void A_Wander(AActor *self, int flags = 0);
|
||||
void A_Chase(VMFrameStack *stack, AActor *self);
|
||||
void A_FaceTarget(AActor *actor);
|
||||
void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0, fixed_t z_add = 0);
|
||||
void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0, fixed_t z_add = 0);
|
||||
|
||||
bool A_RaiseMobj (AActor *, fixed_t speed);
|
||||
bool A_SinkMobj (AActor *, fixed_t speed);
|
||||
|
|
|
@ -478,7 +478,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
|
|||
(floor->m_Direction<0 && floor->m_FloorDestDist<sec->floorplane.d) || // moving down but going up
|
||||
(floor->m_Speed >= abs(sec->floorplane.d - floor->m_FloorDestDist))) // moving in one step
|
||||
{
|
||||
floor->StopInterpolation();
|
||||
floor->StopInterpolation(true);
|
||||
|
||||
// [Graf Zahl]
|
||||
// Don't make sounds for instant movement hacks but make an exception for
|
||||
|
|
|
@ -4222,9 +4222,9 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
|
|||
rail_data.Caller = source;
|
||||
|
||||
rail_data.StopAtOne = !!(railflags & RAF_NOPIERCE);
|
||||
start.X = FIXED2FLOAT(xy.x);
|
||||
start.Y = FIXED2FLOAT(xy.y);
|
||||
start.Z = FIXED2FLOAT(shootz);
|
||||
start.X = FIXED2DBL(xy.x);
|
||||
start.Y = FIXED2DBL(xy.y);
|
||||
start.Z = FIXED2DBL(shootz);
|
||||
|
||||
int flags;
|
||||
|
||||
|
|
|
@ -560,7 +560,7 @@ sector_t *AActor::LinkToWorldForMapThing ()
|
|||
DPrintf ("%s at (%d,%d) lies on %s line %td, distance = %f\n",
|
||||
this->GetClass()->TypeName.GetChars(), X()>>FRACBITS, Y()>>FRACBITS,
|
||||
ldef->dx == 0? "vertical" : ldef->dy == 0? "horizontal" : "diagonal",
|
||||
ldef-lines, FIXED2FLOAT(distance));
|
||||
ldef-lines, FIXED2DBL(distance));
|
||||
angle_t finean = R_PointToAngle2 (0, 0, ldef->dx, ldef->dy);
|
||||
if (ldef->backsector != NULL && ldef->backsector == ssec->sector)
|
||||
{
|
||||
|
|
|
@ -5875,7 +5875,7 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z,
|
|||
// Answer: No, because this way, you can set up sets of parallel missiles.
|
||||
|
||||
fixedvec3 fixvel = source->Vec3To(dest);
|
||||
FVector3 velocity(fixvel.x, fixvel.y, fixvel.z);
|
||||
TVector3<double> velocity(fixvel.x, fixvel.y, fixvel.z);
|
||||
// Floor and ceiling huggers should never have a vertical component to their velocity
|
||||
if (th->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))
|
||||
{
|
||||
|
@ -5887,9 +5887,9 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z,
|
|||
velocity.Z += (dest->height - z + source->Z());
|
||||
}
|
||||
velocity.Resize (speed);
|
||||
th->velx = (fixed_t)(velocity.X);
|
||||
th->vely = (fixed_t)(velocity.Y);
|
||||
th->velz = (fixed_t)(velocity.Z);
|
||||
th->velx = xs_CRoundToInt(velocity.X);
|
||||
th->vely = xs_CRoundToInt(velocity.Y);
|
||||
th->velz = xs_CRoundToInt(velocity.Z);
|
||||
|
||||
// invisible target: rotate velocity vector in 2D
|
||||
// [RC] Now monsters can aim at invisible player as if they were fully visible.
|
||||
|
@ -6163,16 +6163,16 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z,
|
|||
vz = -finesine[pitch>>ANGLETOFINESHIFT];
|
||||
speed = MissileActor->Speed;
|
||||
|
||||
FVector3 vec(vx, vy, vz);
|
||||
TVector3<double> vec(vx, vy, vz);
|
||||
|
||||
if (MissileActor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))
|
||||
{
|
||||
vec.Z = 0;
|
||||
}
|
||||
vec.Resize(speed);
|
||||
MissileActor->velx = (fixed_t)vec.X;
|
||||
MissileActor->vely = (fixed_t)vec.Y;
|
||||
MissileActor->velz = (fixed_t)vec.Z;
|
||||
MissileActor->velx = xs_CRoundToInt(vec.X);
|
||||
MissileActor->vely = xs_CRoundToInt(vec.Y);
|
||||
MissileActor->velz = xs_CRoundToInt(vec.Z);
|
||||
|
||||
if (MissileActor->flags4 & MF4_SPECTRAL)
|
||||
{
|
||||
|
@ -6507,7 +6507,7 @@ DDropItem *AActor::GetDropItems() const
|
|||
fixed_t AActor::GetGravity() const
|
||||
{
|
||||
if (flags & MF_NOGRAVITY) return 0;
|
||||
return fixed_t(level.gravity * Sector->gravity * FIXED2FLOAT(gravity) * 81.92);
|
||||
return fixed_t(level.gravity * Sector->gravity * FIXED2DBL(gravity) * 81.92);
|
||||
}
|
||||
|
||||
// killough 11/98:
|
||||
|
@ -6631,13 +6631,13 @@ void PrintMiscActorInfo(AActor *query)
|
|||
for (flagi = 0; flagi <= 31; flagi++)
|
||||
if (query->flags7 & ActorFlags7::FromInt(1<<flagi)) Printf(" %s", FLAG_NAME(1<<flagi, flags7));
|
||||
Printf("\nBounce flags: %x\nBounce factors: f:%f, w:%f",
|
||||
query->BounceFlags.GetValue(), FIXED2FLOAT(query->bouncefactor),
|
||||
FIXED2FLOAT(query->wallbouncefactor));
|
||||
query->BounceFlags.GetValue(), FIXED2DBL(query->bouncefactor),
|
||||
FIXED2DBL(query->wallbouncefactor));
|
||||
/*for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->BounceFlags & 1<<flagi) Printf(" %s", flagnamesb[flagi]);*/
|
||||
Printf("\nRender style = %i:%s, alpha %f\nRender flags: %x",
|
||||
querystyle, (querystyle < STYLE_Count ? renderstyles[querystyle] : "Unknown"),
|
||||
FIXED2FLOAT(query->alpha), query->renderflags.GetValue());
|
||||
FIXED2DBL(query->alpha), query->renderflags.GetValue());
|
||||
/*for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->renderflags & 1<<flagi) Printf(" %s", flagnamesr[flagi]);*/
|
||||
Printf("\nSpecial+args: %s(%i, %i, %i, %i, %i)\nspecial1: %i, special2: %i.",
|
||||
|
@ -6646,10 +6646,10 @@ void PrintMiscActorInfo(AActor *query)
|
|||
query->args[4], query->special1, query->special2);
|
||||
Printf("\nTID: %d", query->tid);
|
||||
Printf("\nCoord= x: %f, y: %f, z:%f, floor:%f, ceiling:%f.",
|
||||
FIXED2FLOAT(query->X()), FIXED2FLOAT(query->Y()), FIXED2FLOAT(query->Z()),
|
||||
FIXED2FLOAT(query->floorz), FIXED2FLOAT(query->ceilingz));
|
||||
FIXED2DBL(query->X()), FIXED2DBL(query->Y()), FIXED2DBL(query->Z()),
|
||||
FIXED2DBL(query->floorz), FIXED2DBL(query->ceilingz));
|
||||
Printf("\nSpeed= %f, velocity= x:%f, y:%f, z:%f, combined:%f.\n",
|
||||
FIXED2FLOAT(query->Speed), FIXED2FLOAT(query->velx), FIXED2FLOAT(query->vely), FIXED2FLOAT(query->velz),
|
||||
sqrt(pow(FIXED2FLOAT(query->velx), 2) + pow(FIXED2FLOAT(query->vely), 2) + pow(FIXED2FLOAT(query->velz), 2)));
|
||||
FIXED2DBL(query->Speed), FIXED2DBL(query->velx), FIXED2DBL(query->vely), FIXED2DBL(query->velz),
|
||||
sqrt(pow(FIXED2DBL(query->velx), 2) + pow(FIXED2DBL(query->vely), 2) + pow(FIXED2DBL(query->velz), 2)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,17 +75,17 @@ static void P_SlopeLineToPoint (int lineid, fixed_t x, fixed_t y, fixed_t z, boo
|
|||
plane = &sec->floorplane;
|
||||
}
|
||||
|
||||
FVector3 p, v1, v2, cross;
|
||||
TVector3<double> p, v1, v2, cross;
|
||||
|
||||
p[0] = FIXED2FLOAT (line->v1->x);
|
||||
p[1] = FIXED2FLOAT (line->v1->y);
|
||||
p[2] = FIXED2FLOAT (plane->ZatPoint (line->v1->x, line->v1->y));
|
||||
v1[0] = FIXED2FLOAT (line->dx);
|
||||
v1[1] = FIXED2FLOAT (line->dy);
|
||||
v1[2] = FIXED2FLOAT (plane->ZatPoint (line->v2->x, line->v2->y)) - p[2];
|
||||
v2[0] = FIXED2FLOAT (x - line->v1->x);
|
||||
v2[1] = FIXED2FLOAT (y - line->v1->y);
|
||||
v2[2] = FIXED2FLOAT (z) - p[2];
|
||||
p[0] = FIXED2DBL (line->v1->x);
|
||||
p[1] = FIXED2DBL (line->v1->y);
|
||||
p[2] = FIXED2DBL (plane->ZatPoint (line->v1->x, line->v1->y));
|
||||
v1[0] = FIXED2DBL (line->dx);
|
||||
v1[1] = FIXED2DBL (line->dy);
|
||||
v1[2] = FIXED2DBL (plane->ZatPoint (line->v2->x, line->v2->y)) - p[2];
|
||||
v2[0] = FIXED2DBL (x - line->v1->x);
|
||||
v2[1] = FIXED2DBL (y - line->v1->y);
|
||||
v2[2] = FIXED2DBL (z) - p[2];
|
||||
|
||||
cross = v1 ^ v2;
|
||||
double len = cross.Length();
|
||||
|
@ -187,23 +187,23 @@ void P_SetSlope (secplane_t *plane, bool setCeil, int xyangi, int zangi,
|
|||
}
|
||||
xyang = (angle_t)Scale (xyangi, ANGLE_90, 90 << ANGLETOFINESHIFT);
|
||||
|
||||
FVector3 norm;
|
||||
TVector3<double> norm;
|
||||
|
||||
if (ib_compatflags & BCOMPATF_SETSLOPEOVERFLOW)
|
||||
{
|
||||
norm[0] = float(finecosine[zang] * finecosine[xyang]);
|
||||
norm[1] = float(finecosine[zang] * finesine[xyang]);
|
||||
norm[0] = double(finecosine[zang] * finecosine[xyang]);
|
||||
norm[1] = double(finecosine[zang] * finesine[xyang]);
|
||||
}
|
||||
else
|
||||
{
|
||||
norm[0] = float(finecosine[zang]) * float(finecosine[xyang]);
|
||||
norm[1] = float(finecosine[zang]) * float(finesine[xyang]);
|
||||
norm[0] = double(finecosine[zang]) * double(finecosine[xyang]);
|
||||
norm[1] = double(finecosine[zang]) * double(finesine[xyang]);
|
||||
}
|
||||
norm[2] = float(finesine[zang]) * 65536.f;
|
||||
norm[2] = double(finesine[zang]) * 65536.f;
|
||||
norm.MakeUnit();
|
||||
plane->a = (int)(norm[0] * 65536.f);
|
||||
plane->b = (int)(norm[1] * 65536.f);
|
||||
plane->c = (int)(norm[2] * 65536.f);
|
||||
plane->a = FLOAT2FIXED(norm[0]);
|
||||
plane->b = FLOAT2FIXED(norm[1]);
|
||||
plane->c = FLOAT2FIXED(norm[2]);
|
||||
//plane->ic = (int)(65536.f / norm[2]);
|
||||
plane->ic = DivScale32 (1, plane->c);
|
||||
plane->d = -TMulScale16 (plane->a, x,
|
||||
|
@ -226,17 +226,17 @@ void P_VavoomSlope(sector_t * sec, int id, fixed_t x, fixed_t y, fixed_t z, int
|
|||
|
||||
if (l->args[0]==id)
|
||||
{
|
||||
FVector3 v1, v2, cross;
|
||||
TVector3<double> v1, v2, cross;
|
||||
secplane_t *srcplane = (which == 0) ? &sec->floorplane : &sec->ceilingplane;
|
||||
fixed_t srcheight = (which == 0) ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling);
|
||||
|
||||
v1[0] = FIXED2FLOAT (x - l->v2->x);
|
||||
v1[1] = FIXED2FLOAT (y - l->v2->y);
|
||||
v1[2] = FIXED2FLOAT (z - srcheight);
|
||||
v1[0] = FIXED2DBL (x - l->v2->x);
|
||||
v1[1] = FIXED2DBL (y - l->v2->y);
|
||||
v1[2] = FIXED2DBL (z - srcheight);
|
||||
|
||||
v2[0] = FIXED2FLOAT (x - l->v1->x);
|
||||
v2[1] = FIXED2FLOAT (y - l->v1->y);
|
||||
v2[2] = FIXED2FLOAT (z - srcheight);
|
||||
v2[0] = FIXED2DBL (x - l->v1->x);
|
||||
v2[1] = FIXED2DBL (y - l->v1->y);
|
||||
v2[2] = FIXED2DBL (z - srcheight);
|
||||
|
||||
cross = v1 ^ v2;
|
||||
double len = cross.Length();
|
||||
|
@ -334,8 +334,8 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt,
|
|||
sector_t *sec = §ors[i];
|
||||
if (sec->linecount != 3) continue; // only works with triangular sectors
|
||||
|
||||
FVector3 vt1, vt2, vt3, cross;
|
||||
FVector3 vec1, vec2;
|
||||
TVector3<double> vt1, vt2, vt3, cross;
|
||||
TVector3<double> vec1, vec2;
|
||||
int vi1, vi2, vi3;
|
||||
|
||||
vi1 = int(sec->lines[0]->v1 - vertexes);
|
||||
|
@ -343,12 +343,12 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt,
|
|||
vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)?
|
||||
int(sec->lines[1]->v2 - vertexes) : int(sec->lines[1]->v1 - vertexes);
|
||||
|
||||
vt1.X = FIXED2FLOAT(vertexes[vi1].x);
|
||||
vt1.Y = FIXED2FLOAT(vertexes[vi1].y);
|
||||
vt2.X = FIXED2FLOAT(vertexes[vi2].x);
|
||||
vt2.Y = FIXED2FLOAT(vertexes[vi2].y);
|
||||
vt3.X = FIXED2FLOAT(vertexes[vi3].x);
|
||||
vt3.Y = FIXED2FLOAT(vertexes[vi3].y);
|
||||
vt1.X = FIXED2DBL(vertexes[vi1].x);
|
||||
vt1.Y = FIXED2DBL(vertexes[vi1].y);
|
||||
vt2.X = FIXED2DBL(vertexes[vi2].x);
|
||||
vt2.Y = FIXED2DBL(vertexes[vi2].y);
|
||||
vt3.X = FIXED2DBL(vertexes[vi3].x);
|
||||
vt3.Y = FIXED2DBL(vertexes[vi3].y);
|
||||
|
||||
for(int j=0; j<2; j++)
|
||||
{
|
||||
|
@ -358,10 +358,10 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt,
|
|||
fixed_t z3;
|
||||
if (h1==NULL && h2==NULL && h3==NULL) continue;
|
||||
|
||||
vt1.Z = FIXED2FLOAT(h1? *h1 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling));
|
||||
vt2.Z = FIXED2FLOAT(h2? *h2 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling));
|
||||
vt1.Z = FIXED2DBL(h1? *h1 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling));
|
||||
vt2.Z = FIXED2DBL(h2? *h2 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling));
|
||||
z3 = h3? *h3 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling);
|
||||
vt3.Z = FIXED2FLOAT(z3);
|
||||
vt3.Z = FIXED2DBL(z3);
|
||||
|
||||
if (P_PointOnLineSidePrecise(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0)
|
||||
{
|
||||
|
@ -374,7 +374,7 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt,
|
|||
vec2 = vt2 - vt3;
|
||||
}
|
||||
|
||||
FVector3 cross = vec1 ^ vec2;
|
||||
TVector3<double> cross = vec1 ^ vec2;
|
||||
|
||||
double len = cross.Length();
|
||||
if (len == 0)
|
||||
|
@ -519,7 +519,7 @@ static void P_AlignPlane (sector_t *sec, line_t *line, int which)
|
|||
|
||||
refsec = line->frontsector == sec ? line->backsector : line->frontsector;
|
||||
|
||||
FVector3 p, v1, v2, cross;
|
||||
TVector3<double> p, v1, v2, cross;
|
||||
|
||||
secplane_t *srcplane;
|
||||
fixed_t srcheight, destheight;
|
||||
|
@ -528,15 +528,15 @@ static void P_AlignPlane (sector_t *sec, line_t *line, int which)
|
|||
srcheight = (which == 0) ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling);
|
||||
destheight = (which == 0) ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling);
|
||||
|
||||
p[0] = FIXED2FLOAT (line->v1->x);
|
||||
p[1] = FIXED2FLOAT (line->v1->y);
|
||||
p[2] = FIXED2FLOAT (destheight);
|
||||
v1[0] = FIXED2FLOAT (line->dx);
|
||||
v1[1] = FIXED2FLOAT (line->dy);
|
||||
p[0] = FIXED2DBL (line->v1->x);
|
||||
p[1] = FIXED2DBL(line->v1->y);
|
||||
p[2] = FIXED2DBL(destheight);
|
||||
v1[0] = FIXED2DBL(line->dx);
|
||||
v1[1] = FIXED2DBL(line->dy);
|
||||
v1[2] = 0;
|
||||
v2[0] = FIXED2FLOAT (refvert->x - line->v1->x);
|
||||
v2[1] = FIXED2FLOAT (refvert->y - line->v1->y);
|
||||
v2[2] = FIXED2FLOAT (srcheight - destheight);
|
||||
v2[0] = FIXED2DBL(refvert->x - line->v1->x);
|
||||
v2[1] = FIXED2DBL(refvert->y - line->v1->y);
|
||||
v2[2] = FIXED2DBL(srcheight - destheight);
|
||||
|
||||
cross = (v1 ^ v2).Unit();
|
||||
|
||||
|
|
|
@ -2749,13 +2749,13 @@ void P_PredictionLerpReset()
|
|||
|
||||
bool P_LerpCalculate(PredictPos from, PredictPos to, PredictPos &result, float scale)
|
||||
{
|
||||
FVector3 vecFrom(FIXED2DBL(from.x), FIXED2DBL(from.y), FIXED2DBL(from.z));
|
||||
FVector3 vecTo(FIXED2DBL(to.x), FIXED2DBL(to.y), FIXED2DBL(to.z));
|
||||
FVector3 vecResult;
|
||||
TVector3<double> vecFrom(FIXED2DBL(from.x), FIXED2DBL(from.y), FIXED2DBL(from.z));
|
||||
TVector3<double> vecTo(FIXED2DBL(to.x), FIXED2DBL(to.y), FIXED2DBL(to.z));
|
||||
TVector3<double> vecResult;
|
||||
vecResult = vecTo - vecFrom;
|
||||
vecResult *= scale;
|
||||
vecResult = vecResult + vecFrom;
|
||||
FVector3 delta = vecResult - vecTo;
|
||||
TVector3<double> delta = vecResult - vecTo;
|
||||
|
||||
result.x = FLOAT2FIXED(vecResult.X);
|
||||
result.y = FLOAT2FIXED(vecResult.Y);
|
||||
|
|
|
@ -344,9 +344,10 @@ int DInterpolation::AddRef()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int DInterpolation::DelRef()
|
||||
int DInterpolation::DelRef(bool force)
|
||||
{
|
||||
if (refcount > 0) --refcount;
|
||||
if (force && refcount == 0) Destroy();
|
||||
return refcount;
|
||||
}
|
||||
|
||||
|
@ -943,20 +944,6 @@ DInterpolation *sector_t::SetInterpolation(int position, bool attach)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void sector_t::StopInterpolation(int position)
|
||||
{
|
||||
if (interpolations[position] != NULL)
|
||||
{
|
||||
interpolations[position]->DelRef();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DInterpolation *FPolyObj::SetInterpolation()
|
||||
{
|
||||
if (interpolation != NULL)
|
||||
|
|
|
@ -25,7 +25,7 @@ protected:
|
|||
|
||||
public:
|
||||
int AddRef();
|
||||
int DelRef();
|
||||
int DelRef(bool force = false);
|
||||
|
||||
virtual void Destroy();
|
||||
virtual void UpdateInterpolation() = 0;
|
||||
|
|
|
@ -543,7 +543,6 @@ struct sector_t
|
|||
sector_t *GetHeightSec() const;
|
||||
|
||||
DInterpolation *SetInterpolation(int position, bool attach);
|
||||
void StopInterpolation(int position);
|
||||
|
||||
ASkyViewpoint *GetSkyBox(int which);
|
||||
|
||||
|
|
|
@ -714,15 +714,15 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
|||
{ // any mirror--use floats to avoid integer overflow
|
||||
vertex_t *v2 = pds->src->v2;
|
||||
|
||||
float dx = FIXED2FLOAT(v2->x - v1->x);
|
||||
float dy = FIXED2FLOAT(v2->y - v1->y);
|
||||
float x1 = FIXED2FLOAT(v1->x);
|
||||
float y1 = FIXED2FLOAT(v1->y);
|
||||
float x = FIXED2FLOAT(startx);
|
||||
float y = FIXED2FLOAT(starty);
|
||||
double dx = FIXED2DBL(v2->x - v1->x);
|
||||
double dy = FIXED2DBL(v2->y - v1->y);
|
||||
double x1 = FIXED2DBL(v1->x);
|
||||
double y1 = FIXED2DBL(v1->y);
|
||||
double x = FIXED2DBL(startx);
|
||||
double y = FIXED2DBL(starty);
|
||||
|
||||
// the above two cases catch len == 0
|
||||
float r = ((x - x1)*dx + (y - y1)*dy) / (dx*dx + dy*dy);
|
||||
double r = ((x - x1)*dx + (y - y1)*dy) / (dx*dx + dy*dy);
|
||||
|
||||
viewx = FLOAT2FIXED((x1 + r * dx)*2 - x);
|
||||
viewy = FLOAT2FIXED((y1 + r * dy)*2 - y);
|
||||
|
|
|
@ -1652,12 +1652,12 @@ void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
|||
return;
|
||||
}
|
||||
|
||||
double vx = FIXED2FLOAT(viewx);
|
||||
double vy = FIXED2FLOAT(viewy);
|
||||
double vz = FIXED2FLOAT(viewz);
|
||||
double vx = FIXED2DBL(viewx);
|
||||
double vy = FIXED2DBL(viewy);
|
||||
double vz = FIXED2DBL(viewz);
|
||||
|
||||
lxscale = FIXED2FLOAT(pl->xscale) * ifloatpow2[ds_xbits];
|
||||
lyscale = FIXED2FLOAT(pl->yscale) * ifloatpow2[ds_ybits];
|
||||
lxscale = FIXED2DBL(pl->xscale) * ifloatpow2[ds_xbits];
|
||||
lyscale = FIXED2DBL(pl->yscale) * ifloatpow2[ds_ybits];
|
||||
xscale = 64.f / lxscale;
|
||||
yscale = 64.f / lyscale;
|
||||
zeroheight = pl->height.ZatPoint(vx, vy);
|
||||
|
|
|
@ -1631,8 +1631,8 @@ void R_DrawRemainingPlayerSprites()
|
|||
screen->DrawTexture(vis->pic,
|
||||
viewwindowx + VisPSpritesX1[i],
|
||||
viewwindowy + viewheight/2 - (vis->texturemid / 65536.0) * (vis->yscale / 65536.0) - 0.5,
|
||||
DTA_DestWidthF, FIXED2FLOAT(vis->pic->GetWidth() * vis->xscale),
|
||||
DTA_DestHeightF, FIXED2FLOAT(vis->pic->GetHeight() * vis->yscale),
|
||||
DTA_DestWidthF, FIXED2DBL(vis->pic->GetWidth() * vis->xscale),
|
||||
DTA_DestHeightF, FIXED2DBL(vis->pic->GetHeight() * vis->yscale),
|
||||
DTA_Translation, TranslationToTable(vis->Translation),
|
||||
DTA_FlipX, flip,
|
||||
DTA_TopOffset, 0,
|
||||
|
|
|
@ -63,10 +63,6 @@
|
|||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#ifndef FIXED2FLOAT
|
||||
#define FIXED2FLOAT(f) (((float)(f))/(float)65536)
|
||||
#endif
|
||||
|
||||
#define NORM_PITCH 128
|
||||
#define NORM_PRIORITY 64
|
||||
#define NORM_SEP 0
|
||||
|
|
|
@ -250,6 +250,43 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, CountInv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetDistance
|
||||
//
|
||||
// NON-ACTION function to get the distance in double.
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetDistance)
|
||||
{
|
||||
if (numret > 0)
|
||||
{
|
||||
assert(ret != NULL);
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_OBJECT(self, AActor);
|
||||
PARAM_BOOL(checkz);
|
||||
PARAM_INT_OPT(ptr) { ptr = AAPTR_TARGET; }
|
||||
|
||||
AActor *target = COPY_AAPTR(self, ptr);
|
||||
|
||||
if (!target || target == self)
|
||||
{
|
||||
ret->SetFloat(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
fixedvec3 diff = self->Vec3To(target);
|
||||
if (checkz)
|
||||
diff.z += (target->height - self->height) / 2;
|
||||
|
||||
const double length = TVector3<double>(FIXED2DBL(diff.x), FIXED2DBL(diff.y), (checkz) ? FIXED2DBL(diff.z) : 0).Length();
|
||||
ret->SetFloat(length);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_RearrangePointers
|
||||
|
@ -1150,8 +1187,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
|
|||
{
|
||||
if (CMF_OFFSETPITCH & flags)
|
||||
{
|
||||
FVector2 velocity (missile->velx, missile->vely);
|
||||
pitch += R_PointToAngle2(0,0, (fixed_t)velocity.Length(), missile->velz);
|
||||
TVector2<double> velocity (missile->velx, missile->vely);
|
||||
pitch += R_PointToAngle2(0,0, xs_CRoundToInt(velocity.Length()), missile->velz);
|
||||
}
|
||||
ang = pitch >> ANGLETOFINESHIFT;
|
||||
missilespeed = abs(FixedMul(finecosine[ang], missile->Speed));
|
||||
|
@ -1159,8 +1196,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
|
|||
}
|
||||
else
|
||||
{
|
||||
FVector2 velocity (missile->velx, missile->vely);
|
||||
missilespeed = (fixed_t)velocity.Length();
|
||||
TVector2<double> velocity (missile->velx, missile->vely);
|
||||
missilespeed = xs_CRoundToInt(velocity.Length());
|
||||
}
|
||||
|
||||
if (CMF_SAVEPITCH & flags)
|
||||
|
@ -1566,8 +1603,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile)
|
|||
{
|
||||
// This original implementation is to aim straight ahead and then offset
|
||||
// the angle from the resulting direction.
|
||||
FVector3 velocity(misl->velx, misl->vely, 0);
|
||||
fixed_t missilespeed = (fixed_t)velocity.Length();
|
||||
TVector3<double> velocity(misl->velx, misl->vely, 0);
|
||||
fixed_t missilespeed = xs_CRoundToInt(velocity.Length());
|
||||
misl->angle += angle;
|
||||
angle_t an = misl->angle >> ANGLETOFINESHIFT;
|
||||
misl->velx = FixedMul (missilespeed, finecosine[an]);
|
||||
|
@ -3235,7 +3272,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CountdownArg)
|
|||
PARAM_INT(argnum);
|
||||
PARAM_STATE_OPT(state) { state = self->FindState(NAME_Death); }
|
||||
|
||||
if (argnum > 0 && argnum < (int)countof(self->args))
|
||||
if (argnum >= 0 && argnum < (int)countof(self->args))
|
||||
{
|
||||
if (!self->args[argnum]--)
|
||||
{
|
||||
|
@ -6714,8 +6751,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection)
|
|||
if (!(flags & FMDF_NOPITCH))
|
||||
{
|
||||
fixed_t current = mobj->pitch;
|
||||
const FVector2 velocity(mobj->velx, mobj->vely);
|
||||
const fixed_t pitch = R_PointToAngle2(0, 0, (fixed_t)velocity.Length(), -mobj->velz);
|
||||
const TVector2<double> velocity(mobj->velx, mobj->vely);
|
||||
const fixed_t pitch = R_PointToAngle2(0, 0, xs_CRoundToInt(velocity.Length()), -mobj->velz);
|
||||
if (pitchlimit > 0)
|
||||
{
|
||||
// [MC] angle_t for pitchlimit was required because otherwise
|
||||
|
|
|
@ -467,7 +467,8 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
|
|||
PFunction *func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
|
||||
try
|
||||
{
|
||||
if (func != NULL)
|
||||
// There is an action function ACS_NamedExecuteWithResult which must be ignored here for this to work.
|
||||
if (func != NULL && identifier != NAME_ACS_NamedExecuteWithResult)
|
||||
{
|
||||
sc.UnGet();
|
||||
ParseFunctionParameters(sc, cls, *args, func, "", NULL);
|
||||
|
|
|
@ -781,10 +781,10 @@ void DCanvas::VirtualToRealCoordsFixed(fixed_t &x, fixed_t &y, fixed_t &w, fixed
|
|||
{
|
||||
double dx, dy, dw, dh;
|
||||
|
||||
dx = FIXED2FLOAT(x);
|
||||
dy = FIXED2FLOAT(y);
|
||||
dw = FIXED2FLOAT(w);
|
||||
dh = FIXED2FLOAT(h);
|
||||
dx = FIXED2DBL(x);
|
||||
dy = FIXED2DBL(y);
|
||||
dw = FIXED2DBL(w);
|
||||
dh = FIXED2DBL(h);
|
||||
VirtualToRealCoords(dx, dy, dw, dh, vwidth, vheight, vbottom, handleaspect);
|
||||
x = FLOAT2FIXED(dx);
|
||||
y = FLOAT2FIXED(dy);
|
||||
|
@ -1184,8 +1184,8 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
|
|||
return;
|
||||
}
|
||||
|
||||
scalex /= FIXED2FLOAT(tex->xScale);
|
||||
scaley /= FIXED2FLOAT(tex->yScale);
|
||||
scalex /= FIXED2DBL(tex->xScale);
|
||||
scaley /= FIXED2DBL(tex->yScale);
|
||||
|
||||
cosrot = cos(rot);
|
||||
sinrot = sin(rot);
|
||||
|
|
|
@ -41,6 +41,7 @@ ACTOR Actor native //: Thinker
|
|||
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
|
||||
native bool IsPointerEqual(int ptr_select1, int ptr_select2);
|
||||
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);
|
||||
native float GetDistance(bool checkz, int ptr = AAPTR_DEFAULT);
|
||||
|
||||
// Action functions
|
||||
// Meh, MBF redundant functions. Only for DeHackEd support.
|
||||
|
@ -149,7 +150,7 @@ ACTOR Actor native //: Thinker
|
|||
action native A_SkullPop(class<PlayerChunk> skulltype = "BloodySkull");
|
||||
action native A_CheckPlayerDone();
|
||||
|
||||
action native A_Wander();
|
||||
action native A_Wander(int flags = 0);
|
||||
action native A_Look2();
|
||||
action native A_TossGib();
|
||||
action native A_SentinelBob();
|
||||
|
|
|
@ -79,11 +79,20 @@ const int SXF_ISMASTER = 1 << 27;
|
|||
const int SXF_ISTRACER = 1 << 28;
|
||||
|
||||
// Flags for A_Chase
|
||||
const int CHF_FASTCHASE = 1;
|
||||
const int CHF_NOPLAYACTIVE = 2;
|
||||
const int CHF_NIGHTMAREFAST = 4;
|
||||
const int CHF_RESURRECT = 8;
|
||||
const int CHF_DONTMOVE = 16;
|
||||
enum
|
||||
{
|
||||
CHF_FASTCHASE = 1,
|
||||
CHF_NOPLAYACTIVE = 2,
|
||||
CHF_NIGHTMAREFAST = 4,
|
||||
CHF_RESURRECT = 8,
|
||||
CHF_DONTMOVE = 16,
|
||||
CHF_NORANDOMTURN = 32,
|
||||
CHF_NODIRECTIONTURN = 64,
|
||||
CHF_NOPOSTATTACKTURN = 128,
|
||||
CHF_STOPIFBLOCKED = 256,
|
||||
|
||||
CHF_DONTTURN = CHF_NORANDOMTURN | CHF_NOPOSTATTACKTURN | CHF_STOPIFBLOCKED
|
||||
};
|
||||
|
||||
// Flags for A_LookEx
|
||||
const int LOF_NOSIGHTCHECK = 1;
|
||||
|
|
Loading…
Reference in a new issue