mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-17 08:01:55 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
4e7cfef0e0
11 changed files with 250 additions and 137 deletions
|
@ -71,8 +71,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
||||||
if (linetarget)
|
if (linetarget)
|
||||||
{
|
{
|
||||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindClass ("CStaffPuff"), false, &linetarget);
|
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindClass ("CStaffPuff"), false, &linetarget);
|
||||||
pmo->angle = R_PointToAngle2 (pmo->x, pmo->y,
|
if (linetarget != NULL)
|
||||||
linetarget->x, linetarget->y);
|
{
|
||||||
|
pmo->angle = R_PointToAngle2 (pmo->x, pmo->y, linetarget->x, linetarget->y);
|
||||||
if (((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0))|| linetarget->flags3&MF3_ISMONSTER)
|
if (((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0))|| linetarget->flags3&MF3_ISMONSTER)
|
||||||
&& (!(linetarget->flags2&(MF2_DORMANT+MF2_INVULNERABLE))))
|
&& (!(linetarget->flags2&(MF2_DORMANT+MF2_INVULNERABLE))))
|
||||||
{
|
{
|
||||||
|
@ -88,6 +89,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
||||||
{
|
{
|
||||||
weapon->DepleteAmmo (weapon->bAltFire, false);
|
weapon->DepleteAmmo (weapon->bAltFire, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
angle = pmo->angle-i*(ANG45/16);
|
angle = pmo->angle-i*(ANG45/16);
|
||||||
|
@ -95,8 +97,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
||||||
if (linetarget)
|
if (linetarget)
|
||||||
{
|
{
|
||||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindClass ("CStaffPuff"), false, &linetarget);
|
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindClass ("CStaffPuff"), false, &linetarget);
|
||||||
pmo->angle = R_PointToAngle2 (pmo->x, pmo->y,
|
if (linetarget != NULL)
|
||||||
linetarget->x, linetarget->y);
|
{
|
||||||
|
pmo->angle = R_PointToAngle2 (pmo->x, pmo->y, linetarget->x, linetarget->y);
|
||||||
if ((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0)) || linetarget->flags3&MF3_ISMONSTER)
|
if ((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0)) || linetarget->flags3&MF3_ISMONSTER)
|
||||||
{
|
{
|
||||||
newLife = player->health+(damage>>4);
|
newLife = player->health+(damage>>4);
|
||||||
|
@ -104,7 +107,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
||||||
pmo->health = player->health = newLife;
|
pmo->health = player->health = newLife;
|
||||||
P_SetPsprite (player, ps_weapon, weapon->FindState ("Drain"));
|
P_SetPsprite (player, ps_weapon, weapon->FindState ("Drain"));
|
||||||
}
|
}
|
||||||
|
if (weapon != NULL)
|
||||||
|
{
|
||||||
weapon->DepleteAmmo (weapon->bAltFire, false);
|
weapon->DepleteAmmo (weapon->bAltFire, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int in
|
||||||
m_IntensityX = intensityX;
|
m_IntensityX = intensityX;
|
||||||
m_IntensityY = intensityY;
|
m_IntensityY = intensityY;
|
||||||
m_IntensityZ = intensityZ;
|
m_IntensityZ = intensityZ;
|
||||||
m_CountdownStart = (double)duration;
|
m_CountdownStart = duration;
|
||||||
m_Countdown = duration;
|
m_Countdown = duration;
|
||||||
m_Flags = flags;
|
m_Flags = flags;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,48 @@ void DEarthquake::Tick ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// DEarthquake :: GetModIntensity
|
||||||
|
//
|
||||||
|
// Given a base intensity, modify it according to the quake's flags.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
fixed_t DEarthquake::GetModIntensity(int intensity) const
|
||||||
|
{
|
||||||
|
assert(m_CountdownStart >= m_Countdown);
|
||||||
|
intensity += intensity; // always doubled
|
||||||
|
if (m_Flags & (QF_SCALEDOWN | QF_SCALEUP))
|
||||||
|
{
|
||||||
|
int scalar;
|
||||||
|
if ((m_Flags & (QF_SCALEDOWN | QF_SCALEUP)) == (QF_SCALEDOWN | QF_SCALEUP))
|
||||||
|
{
|
||||||
|
scalar = (m_Flags & QF_MAX) ? MAX(m_Countdown, m_CountdownStart - m_Countdown)
|
||||||
|
: MIN(m_Countdown, m_CountdownStart - m_Countdown);
|
||||||
|
if (m_Flags & QF_FULLINTENSITY)
|
||||||
|
{
|
||||||
|
scalar *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_Flags & QF_SCALEDOWN)
|
||||||
|
{
|
||||||
|
scalar = m_Countdown;
|
||||||
|
}
|
||||||
|
else // QF_SCALEUP
|
||||||
|
{
|
||||||
|
scalar = m_CountdownStart - m_Countdown;
|
||||||
|
}
|
||||||
|
assert(m_CountdownStart > 0);
|
||||||
|
intensity = intensity * (scalar << FRACBITS) / m_CountdownStart;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
intensity <<= FRACBITS;
|
||||||
|
}
|
||||||
|
return intensity;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// DEarthquake::StaticGetQuakeIntensity
|
// DEarthquake::StaticGetQuakeIntensity
|
||||||
|
@ -160,14 +202,15 @@ void DEarthquake::Tick ()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int DEarthquake::StaticGetQuakeIntensities(AActor *victim, quakeInfo &qprop)
|
int DEarthquake::StaticGetQuakeIntensities(AActor *victim,
|
||||||
|
fixed_t &intensityX, fixed_t &intensityY, fixed_t &intensityZ,
|
||||||
|
fixed_t &relIntensityX, fixed_t &relIntensityY, fixed_t &relIntensityZ)
|
||||||
{
|
{
|
||||||
if (victim->player != NULL && (victim->player->cheats & CF_NOCLIP))
|
if (victim->player != NULL && (victim->player->cheats & CF_NOCLIP))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
qprop.isScalingDown = qprop.isScalingUp = qprop.preferMaximum = qprop.fullIntensity = false;
|
intensityX = intensityY = intensityZ = relIntensityX = relIntensityY = relIntensityZ = 0;
|
||||||
qprop.intensityX = qprop.intensityY = qprop.intensityZ = qprop.relIntensityX = qprop.relIntensityY = qprop.relIntensityZ = 0;
|
|
||||||
|
|
||||||
TThinkerIterator<DEarthquake> iterator(STAT_EARTHQUAKE);
|
TThinkerIterator<DEarthquake> iterator(STAT_EARTHQUAKE);
|
||||||
DEarthquake *quake;
|
DEarthquake *quake;
|
||||||
|
@ -182,30 +225,20 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, quakeInfo &qprop)
|
||||||
if (dist < quake->m_TremorRadius)
|
if (dist < quake->m_TremorRadius)
|
||||||
{
|
{
|
||||||
++count;
|
++count;
|
||||||
|
fixed_t x = quake->GetModIntensity(quake->m_IntensityX);
|
||||||
|
fixed_t y = quake->GetModIntensity(quake->m_IntensityY);
|
||||||
|
fixed_t z = quake->GetModIntensity(quake->m_IntensityZ);
|
||||||
if (quake->m_Flags & QF_RELATIVE)
|
if (quake->m_Flags & QF_RELATIVE)
|
||||||
{
|
{
|
||||||
qprop.relIntensityX = MAX(qprop.relIntensityX, quake->m_IntensityX);
|
relIntensityX = MAX(relIntensityX, x);
|
||||||
qprop.relIntensityY = MAX(qprop.relIntensityY, quake->m_IntensityY);
|
relIntensityY = MAX(relIntensityY, y);
|
||||||
qprop.relIntensityZ = MAX(qprop.relIntensityZ, quake->m_IntensityZ);
|
relIntensityZ = MAX(relIntensityZ, z);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qprop.intensityX = MAX(qprop.intensityX, quake->m_IntensityX);
|
intensityX = MAX(intensityX, x);
|
||||||
qprop.intensityY = MAX(qprop.intensityY, quake->m_IntensityY);
|
intensityY = MAX(intensityY, y);
|
||||||
qprop.intensityZ = MAX(qprop.intensityZ, quake->m_IntensityZ);
|
intensityZ = MAX(intensityZ, z);
|
||||||
}
|
|
||||||
if (quake->m_Flags)
|
|
||||||
{
|
|
||||||
qprop.scaleDownStart = quake->m_CountdownStart;
|
|
||||||
qprop.scaleDown = quake->m_Countdown;
|
|
||||||
qprop.isScalingDown = (quake->m_Flags & QF_SCALEDOWN) ? true : false;
|
|
||||||
qprop.isScalingUp = (quake->m_Flags & QF_SCALEUP) ? true : false;
|
|
||||||
qprop.preferMaximum = (quake->m_Flags & QF_MAX) ? true : false;
|
|
||||||
qprop.fullIntensity = (quake->m_Flags & QF_FULLINTENSITY) ? true : false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qprop.scaleDownStart = qprop.scaleDown = 0.0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,13 +140,6 @@ enum
|
||||||
QF_FULLINTENSITY = 1 << 4,
|
QF_FULLINTENSITY = 1 << 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct quakeInfo
|
|
||||||
{
|
|
||||||
int intensityX, intensityY, intensityZ, relIntensityX, relIntensityY, relIntensityZ;
|
|
||||||
double scaleDown, scaleDownStart;
|
|
||||||
bool isScalingDown, isScalingUp, preferMaximum, fullIntensity;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DEarthquake : public DThinker
|
class DEarthquake : public DThinker
|
||||||
{
|
{
|
||||||
DECLARE_CLASS (DEarthquake, DThinker)
|
DECLARE_CLASS (DEarthquake, DThinker)
|
||||||
|
@ -159,12 +152,16 @@ public:
|
||||||
TObjPtr<AActor> m_Spot;
|
TObjPtr<AActor> m_Spot;
|
||||||
fixed_t m_TremorRadius, m_DamageRadius;
|
fixed_t m_TremorRadius, m_DamageRadius;
|
||||||
int m_Countdown;
|
int m_Countdown;
|
||||||
double m_CountdownStart;
|
int m_CountdownStart;
|
||||||
FSoundID m_QuakeSFX;
|
FSoundID m_QuakeSFX;
|
||||||
int m_Flags;
|
int m_Flags;
|
||||||
int m_IntensityX, m_IntensityY, m_IntensityZ;
|
int m_IntensityX, m_IntensityY, m_IntensityZ;
|
||||||
|
|
||||||
static int StaticGetQuakeIntensities(AActor *viewer, quakeInfo &qprop);
|
fixed_t GetModIntensity(int intensity) const;
|
||||||
|
|
||||||
|
static int StaticGetQuakeIntensities(AActor *viewer,
|
||||||
|
fixed_t &intensityX, fixed_t &intensityY, fixed_t &intensityZ,
|
||||||
|
fixed_t &relIntensityX, fixed_t &relIntensityY, fixed_t &relIntensityZ);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DEarthquake ();
|
DEarthquake ();
|
||||||
|
|
|
@ -343,8 +343,6 @@ int GetUDMFInt(int type, int index, const char *key)
|
||||||
{
|
{
|
||||||
assert(type >=0 && type <=3);
|
assert(type >=0 && type <=3);
|
||||||
|
|
||||||
if (index > 0)
|
|
||||||
{
|
|
||||||
FUDMFKeys *pKeys = UDMFKeys[type].CheckKey(index);
|
FUDMFKeys *pKeys = UDMFKeys[type].CheckKey(index);
|
||||||
|
|
||||||
if (pKeys != NULL)
|
if (pKeys != NULL)
|
||||||
|
@ -355,7 +353,6 @@ int GetUDMFInt(int type, int index, const char *key)
|
||||||
return pKey->IntVal;
|
return pKey->IntVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,8 +360,6 @@ fixed_t GetUDMFFixed(int type, int index, const char *key)
|
||||||
{
|
{
|
||||||
assert(type >=0 && type <=3);
|
assert(type >=0 && type <=3);
|
||||||
|
|
||||||
if (index > 0)
|
|
||||||
{
|
|
||||||
FUDMFKeys *pKeys = UDMFKeys[type].CheckKey(index);
|
FUDMFKeys *pKeys = UDMFKeys[type].CheckKey(index);
|
||||||
|
|
||||||
if (pKeys != NULL)
|
if (pKeys != NULL)
|
||||||
|
@ -375,7 +370,6 @@ fixed_t GetUDMFFixed(int type, int index, const char *key)
|
||||||
return FLOAT2FIXED(pKey->FloatVal);
|
return FLOAT2FIXED(pKey->FloatVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,6 +1103,7 @@ public:
|
||||||
sdt->midtexture = "-";
|
sdt->midtexture = "-";
|
||||||
sd->SetTextureXScale(FRACUNIT);
|
sd->SetTextureXScale(FRACUNIT);
|
||||||
sd->SetTextureYScale(FRACUNIT);
|
sd->SetTextureYScale(FRACUNIT);
|
||||||
|
sd->Index = index;
|
||||||
|
|
||||||
sc.MustGetToken('{');
|
sc.MustGetToken('{');
|
||||||
while (!sc.CheckToken('}'))
|
while (!sc.CheckToken('}'))
|
||||||
|
|
|
@ -1512,11 +1512,11 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
||||||
yscale = pl->yscale << (16 - ds_ybits);
|
yscale = pl->yscale << (16 - ds_ybits);
|
||||||
if (planeang != 0)
|
if (planeang != 0)
|
||||||
{
|
{
|
||||||
fixed_t cosine = finecosine[planeang >> ANGLETOFINESHIFT];
|
double rad = bam2rad(planeang);
|
||||||
fixed_t sine = finesine[planeang >> ANGLETOFINESHIFT];
|
double cosine = cos(rad), sine = sin(rad);
|
||||||
|
|
||||||
pviewx = pl->xoffs + FixedMul (viewx, cosine) - FixedMul (viewy, sine);
|
pviewx = xs_RoundToInt(pl->xoffs + viewx * cosine - viewy * sine);
|
||||||
pviewy = pl->yoffs - FixedMul (viewx, sine) - FixedMul (viewy, cosine);
|
pviewy = xs_RoundToInt(pl->yoffs - viewx * sine - viewy * cosine);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -770,45 +770,9 @@ bool R_GetViewInterpolationStatus()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static fixed_t QuakePower(double factor, int intensity, quakeInfo quake)
|
static fixed_t QuakePower(fixed_t factor, fixed_t intensity)
|
||||||
{
|
{
|
||||||
double scaleDownStart = quake.scaleDownStart;
|
return FixedMul(factor, pr_torchflicker(intensity * 2) - intensity);
|
||||||
double scaleDown = quake.scaleDown;
|
|
||||||
if (intensity == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double ss = (double)((pr_torchflicker() % (intensity << 2)) - (intensity << 1));
|
|
||||||
double mtp = (quake.fullIntensity) ? 2.0 : 1.0;
|
|
||||||
if (quake.isScalingDown || quake.isScalingUp)
|
|
||||||
{
|
|
||||||
fixed_t result;
|
|
||||||
if (scaleDownStart == 0) scaleDownStart = 1;
|
|
||||||
|
|
||||||
if (quake.isScalingDown && quake.isScalingUp)
|
|
||||||
{
|
|
||||||
if (quake.preferMaximum)
|
|
||||||
result = FLOAT2FIXED((factor * ss) * MAX(((scaleDown*mtp) / scaleDownStart), ((scaleDownStart - scaleDown)*mtp) / scaleDownStart));
|
|
||||||
else
|
|
||||||
result = FLOAT2FIXED((factor * ss) * MIN(((scaleDown*mtp) / scaleDownStart), ((scaleDownStart - scaleDown)*mtp) / scaleDownStart));
|
|
||||||
}
|
|
||||||
else if (quake.isScalingDown)
|
|
||||||
result = FLOAT2FIXED((factor * ss) * (scaleDown / scaleDownStart));
|
|
||||||
else if (quake.isScalingUp)
|
|
||||||
result = FLOAT2FIXED((factor * ss) * ((scaleDownStart - scaleDown) / scaleDownStart));
|
|
||||||
else
|
|
||||||
result = FLOAT2FIXED(factor * ss);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return FLOAT2FIXED(factor * ss);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -921,38 +885,40 @@ void R_SetupFrame (AActor *actor)
|
||||||
|
|
||||||
if (!paused)
|
if (!paused)
|
||||||
{
|
{
|
||||||
quakeInfo quake;
|
fixed_t intensityX, intensityY, intensityZ, relIntensityX, relIntensityY, relIntensityZ;
|
||||||
if (DEarthquake::StaticGetQuakeIntensities(camera, quake) > 0)
|
if (DEarthquake::StaticGetQuakeIntensities(camera,
|
||||||
|
intensityX, intensityY, intensityZ,
|
||||||
|
relIntensityX, relIntensityY, relIntensityZ) > 0)
|
||||||
{
|
{
|
||||||
double quakefactor = r_quakeintensity;
|
fixed_t quakefactor = FLOAT2FIXED(r_quakeintensity);
|
||||||
|
|
||||||
if (quake.relIntensityX != 0)
|
if (relIntensityX != 0)
|
||||||
{
|
{
|
||||||
int ang = (camera->angle) >> ANGLETOFINESHIFT;
|
int ang = (camera->angle) >> ANGLETOFINESHIFT;
|
||||||
fixed_t power = QuakePower(quakefactor, quake.relIntensityX, quake);
|
fixed_t power = QuakePower(quakefactor, relIntensityX);
|
||||||
viewx += FixedMul(finecosine[ang], power);
|
viewx += FixedMul(finecosine[ang], power);
|
||||||
viewy += FixedMul(finesine[ang], power);
|
viewy += FixedMul(finesine[ang], power);
|
||||||
}
|
}
|
||||||
if (quake.relIntensityY != 0)
|
if (relIntensityY != 0)
|
||||||
{
|
{
|
||||||
int ang = (camera->angle + ANG90) >> ANGLETOFINESHIFT;
|
int ang = (camera->angle + ANG90) >> ANGLETOFINESHIFT;
|
||||||
fixed_t power = QuakePower(quakefactor, quake.relIntensityY, quake);
|
fixed_t power = QuakePower(quakefactor, relIntensityY);
|
||||||
viewx += FixedMul(finecosine[ang], power);
|
viewx += FixedMul(finecosine[ang], power);
|
||||||
viewy += FixedMul(finesine[ang], power);
|
viewy += FixedMul(finesine[ang], power);
|
||||||
}
|
}
|
||||||
if (quake.intensityX != 0)
|
if (intensityX != 0)
|
||||||
{
|
{
|
||||||
viewx += QuakePower(quakefactor, quake.intensityX, quake);
|
viewx += QuakePower(quakefactor, intensityX);
|
||||||
}
|
}
|
||||||
if (quake.intensityY != 0)
|
if (intensityY != 0)
|
||||||
{
|
{
|
||||||
viewy += QuakePower(quakefactor, quake.intensityY, quake);
|
viewy += QuakePower(quakefactor, intensityY);
|
||||||
}
|
}
|
||||||
// FIXME: Relative Z is not relative
|
// FIXME: Relative Z is not relative
|
||||||
quake.intensityZ = MAX(quake.intensityZ, quake.relIntensityZ);
|
intensityZ = MAX(intensityZ, relIntensityZ);
|
||||||
if (quake.intensityZ != 0)
|
if (intensityZ != 0)
|
||||||
{
|
{
|
||||||
viewz += QuakePower(quakefactor, quake.intensityZ, quake);
|
viewz += QuakePower(quakefactor, intensityZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,7 @@ std2:
|
||||||
'random2' { RET(TK_Random2); }
|
'random2' { RET(TK_Random2); }
|
||||||
'frandom' { RET(TK_FRandom); }
|
'frandom' { RET(TK_FRandom); }
|
||||||
'randompick' { RET(TK_RandomPick); }
|
'randompick' { RET(TK_RandomPick); }
|
||||||
|
'frandompick' { RET(TK_FRandomPick); }
|
||||||
|
|
||||||
L (L|D)* { RET(TK_Identifier); }
|
L (L|D)* { RET(TK_Identifier); }
|
||||||
|
|
||||||
|
|
|
@ -123,4 +123,5 @@ xx(TK_In, "'in'")
|
||||||
xx(TK_SizeOf, "'sizeof'")
|
xx(TK_SizeOf, "'sizeof'")
|
||||||
xx(TK_AlignOf, "'alignof'")
|
xx(TK_AlignOf, "'alignof'")
|
||||||
xx(TK_RandomPick, "'randompick'")
|
xx(TK_RandomPick, "'randompick'")
|
||||||
|
xx(TK_FRandomPick, "'frandompick'")
|
||||||
#undef xx
|
#undef xx
|
||||||
|
|
|
@ -371,8 +371,9 @@ static FxExpression *ParseExpression0 (FScanner &sc, const PClass *cls)
|
||||||
|
|
||||||
return new FxRandom(rng, min, max, sc);
|
return new FxRandom(rng, min, max, sc);
|
||||||
}
|
}
|
||||||
else if (sc.CheckToken(TK_RandomPick))
|
else if (sc.CheckToken(TK_RandomPick) || sc.CheckToken(TK_FRandomPick))
|
||||||
{
|
{
|
||||||
|
bool floaty = sc.TokenType == TK_FRandomPick;
|
||||||
FRandom *rng;
|
FRandom *rng;
|
||||||
TArray<FxExpression*> list;
|
TArray<FxExpression*> list;
|
||||||
list.Clear();
|
list.Clear();
|
||||||
|
@ -398,7 +399,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, const PClass *cls)
|
||||||
break;
|
break;
|
||||||
sc.MustGetToken(',');
|
sc.MustGetToken(',');
|
||||||
}
|
}
|
||||||
return new FxRandomPick(rng, list, sc);
|
return new FxRandomPick(rng, list, floaty, sc);
|
||||||
}
|
}
|
||||||
else if (sc.CheckToken(TK_FRandom))
|
else if (sc.CheckToken(TK_FRandom))
|
||||||
{
|
{
|
||||||
|
|
|
@ -314,6 +314,25 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
class FxFloatCast : public FxExpression
|
||||||
|
{
|
||||||
|
FxExpression *basex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FxFloatCast(FxExpression *x);
|
||||||
|
~FxFloatCast();
|
||||||
|
FxExpression *Resolve(FCompileContext&);
|
||||||
|
|
||||||
|
ExpVal EvalExpression (AActor *self);
|
||||||
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FxSign
|
// FxSign
|
||||||
|
@ -568,7 +587,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FxRandomPick(FRandom *, TArray<FxExpression*> mi, const FScriptPosition &pos);
|
FxRandomPick(FRandom *, TArray<FxExpression*> mi, bool floaty, const FScriptPosition &pos);
|
||||||
~FxRandomPick();
|
~FxRandomPick();
|
||||||
FxExpression *Resolve(FCompileContext&);
|
FxExpression *Resolve(FCompileContext&);
|
||||||
|
|
||||||
|
|
|
@ -446,6 +446,82 @@ ExpVal FxIntCast::EvalExpression (AActor *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FxFloatCast::FxFloatCast(FxExpression *x)
|
||||||
|
: FxExpression(x->ScriptPosition)
|
||||||
|
{
|
||||||
|
basex = x;
|
||||||
|
ValueType = VAL_Float;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FxFloatCast::~FxFloatCast()
|
||||||
|
{
|
||||||
|
SAFE_DELETE(basex);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FxExpression *FxFloatCast::Resolve(FCompileContext &ctx)
|
||||||
|
{
|
||||||
|
CHECKRESOLVED();
|
||||||
|
SAFE_RESOLVE(basex, ctx);
|
||||||
|
|
||||||
|
if (basex->ValueType == VAL_Float)
|
||||||
|
{
|
||||||
|
FxExpression *x = basex;
|
||||||
|
basex = NULL;
|
||||||
|
delete this;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
else if (basex->ValueType == VAL_Int)
|
||||||
|
{
|
||||||
|
if (basex->isConstant())
|
||||||
|
{
|
||||||
|
ExpVal constval = basex->EvalExpression(NULL);
|
||||||
|
FxExpression *x = new FxConstant(constval.GetFloat(), ScriptPosition);
|
||||||
|
delete this;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
|
||||||
|
delete this;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
ExpVal FxFloatCast::EvalExpression (AActor *self)
|
||||||
|
{
|
||||||
|
ExpVal baseval = basex->EvalExpression(self);
|
||||||
|
baseval.Float = baseval.GetFloat();
|
||||||
|
baseval.Type = VAL_Float;
|
||||||
|
return baseval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -1698,15 +1774,24 @@ ExpVal FxRandom::EvalExpression (AActor *self)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
FxRandomPick::FxRandomPick(FRandom * r, TArray<FxExpression*> mi, const FScriptPosition &pos)
|
FxRandomPick::FxRandomPick(FRandom * r, TArray<FxExpression*> mi, bool floaty, const FScriptPosition &pos)
|
||||||
: FxExpression(pos)
|
: FxExpression(pos)
|
||||||
{
|
{
|
||||||
for (unsigned int index = 0; index < mi.Size(); index++)
|
for (unsigned int index = 0; index < mi.Size(); index++)
|
||||||
{
|
{
|
||||||
min.Push(new FxIntCast(mi[index]));
|
FxExpression *casted;
|
||||||
|
if (floaty)
|
||||||
|
{
|
||||||
|
casted = new FxFloatCast(mi[index]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
casted = new FxIntCast(mi[index]);
|
||||||
|
}
|
||||||
|
min.Push(casted);
|
||||||
}
|
}
|
||||||
rng = r;
|
rng = r;
|
||||||
ValueType = VAL_Int;
|
ValueType = floaty ? VAL_Float : VAL_Int;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1746,17 +1831,25 @@ FxExpression *FxRandomPick::Resolve(FCompileContext &ctx)
|
||||||
ExpVal FxRandomPick::EvalExpression(AActor *self)
|
ExpVal FxRandomPick::EvalExpression(AActor *self)
|
||||||
{
|
{
|
||||||
ExpVal val;
|
ExpVal val;
|
||||||
val.Type = VAL_Int;
|
|
||||||
int max = min.Size();
|
int max = min.Size();
|
||||||
if (max > 0)
|
if (max > 0)
|
||||||
{
|
{
|
||||||
int select = (*rng)(max);
|
int select = (*rng)(max);
|
||||||
val.Int = min[select]->EvalExpression(self).GetInt();
|
val = min[select]->EvalExpression(self);
|
||||||
|
}
|
||||||
|
/* Is a default even important when the parser requires at least one
|
||||||
|
* choice? Why do we do this? */
|
||||||
|
else if (ValueType == VAL_Int)
|
||||||
|
{
|
||||||
|
val.Type = VAL_Int;
|
||||||
|
val.Int = (*rng)();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val.Int = (*rng)();
|
val.Type = VAL_Float;
|
||||||
|
val.Float = (*rng)(0x40000000) / double(0x40000000);
|
||||||
}
|
}
|
||||||
|
assert(val.Type == ValueType.Type);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue