- g_hexen almost done except for 3 things that require more extensive changes.

This commit is contained in:
Christoph Oelckers 2016-03-21 22:20:10 +01:00
parent f1602882c8
commit c830801da3
31 changed files with 311 additions and 355 deletions

View file

@ -127,7 +127,7 @@ bool DBot::Check_LOS (AActor *to, angle_t vangle)
if (vangle == 0) if (vangle == 0)
return false; //Looker seems to be blind. return false; //Looker seems to be blind.
return absangle(player->mo->__f_AngleTo(to) - player->mo->_f_angle()) <= vangle/2; return absangle(player->mo->AngleTo(to), player->mo->Angles.Yaw) <= ANGLE2FLOAT(vangle/2);
} }
//------------------------------------- //-------------------------------------

View file

@ -39,7 +39,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn)
AActor *mo; AActor *mo;
int delta; int delta;
angle_t angle; DAngle angle;
// Countdown until next spawn // Countdown until next spawn
if (self->special1-- > 0) return 0; if (self->special1-- > 0) return 0;
@ -47,7 +47,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn)
delta = self->args[1]; delta = self->args[1];
if (delta==0) delta=1; if (delta==0) delta=1;
angle = self->_f_angle() + (((pr_batspawn()%delta)-(delta>>1))<<24);
angle = self->Angles.Yaw + (((pr_batspawn() % delta) - (delta >> 1)) * (360 / 256.));
mo = P_SpawnMissileAngle (self, PClass::FindActor("Bat"), angle, 0); mo = P_SpawnMissileAngle (self, PClass::FindActor("Bat"), angle, 0);
if (mo) if (mo)
{ {
@ -90,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove)
} }
// Handle Z movement // Handle Z movement
self->SetZ(self->target->Z() + 16 * g_sin(BOBTORAD(self->args[0]))); self->SetZ(self->target->Z() + 2 * BobSin(self->args[0]));
self->args[0] = (self->args[0]+3)&63; self->args[0] = (self->args[0]+3)&63;
return 0; return 0;
} }

View file

@ -80,7 +80,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
A_Weave(self, 2, 2, 2*FRACUNIT, FRACUNIT); A_Weave(self, 2, 2, 2., 1.);
return 0; return 0;
} }
@ -174,10 +174,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopChase)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
fixed_t newz = self->_f_Z() - finesine[self->special2 << BOBTOFINESHIFT] * 4; double newz = self->Z() - BobSin(self->special2) / 2.;
self->special2 = (self->special2 + 4) & 63; self->special2 = (self->special2 + 4) & 63;
newz += finesine[self->special2 << BOBTOFINESHIFT] * 4; newz += BobSin(self->special2) / 2.;
self->_f_SetZ(newz); self->SetZ(newz);
return 0; return 0;
} }
@ -193,7 +193,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff)
AActor *mo; AActor *mo;
mo = Spawn ("BishopPuff", self->PosPlusZ(40*FRACUNIT), ALLOW_REPLACE); mo = Spawn ("BishopPuff", self->PosPlusZ(40.), ALLOW_REPLACE);
if (mo) if (mo)
{ {
mo->Vel.Z = -.5; mo->Vel.Z = -.5;
@ -218,9 +218,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur)
self->SetState (self->FindState ("Blur")); self->SetState (self->FindState ("Blur"));
return 0; return 0;
} }
fixed_t xo = (pr_pain.Random2() << 12); double xo = pr_pain.Random2() / 16.;
fixed_t yo = (pr_pain.Random2() << 12); double yo = pr_pain.Random2() / 16.;
fixed_t zo = (pr_pain.Random2() << 11); double zo = pr_pain.Random2() / 32.;
mo = Spawn ("BishopPainBlur", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); mo = Spawn ("BishopPainBlur", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo) if (mo)
{ {

View file

@ -44,7 +44,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
if (t.linetarget != NULL) if (t.linetarget != NULL)
{ {
AdjustPlayerAngle(player->mo, &t); AdjustPlayerAngle(player->mo, &t);
goto macedone; return 0;
} }
} }
} }
@ -55,6 +55,5 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
angle = player->mo->Angles.Yaw; angle = player->mo->Angles.Yaw;
slope = P_AimLineAttack (player->mo, angle, MELEERANGE); slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, hammertime); P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, hammertime);
macedone:
return 0; return 0;
} }

View file

@ -29,8 +29,8 @@ static void DragonSeek (AActor *actor, DAngle thresh, DAngle turnMax)
DAngle delta; DAngle delta;
AActor *target; AActor *target;
int i; int i;
angle_t bestAngle; DAngle bestAngle;
angle_t angleToSpot, angleToTarget; DAngle angleToSpot, angleToTarget;
AActor *mo; AActor *mo;
target = actor->tracer; target = actor->tracer;
@ -66,8 +66,8 @@ static void DragonSeek (AActor *actor, DAngle thresh, DAngle turnMax)
if (target->flags&MF_SHOOTABLE && pr_dragonseek() < 64) if (target->flags&MF_SHOOTABLE && pr_dragonseek() < 64)
{ // attack the destination mobj if it's attackable { // attack the destination mobj if it's attackable
AActor *oldTarget; AActor *oldTarget;
if (absangle(actor->_f_angle() - actor->__f_AngleTo(target)) < ANGLE_45/2) if (absangle(actor->Angles.Yaw, actor->AngleTo(target)) < 22.5)
{ {
oldTarget = actor->target; oldTarget = actor->target;
actor->target = target; actor->target = target;
@ -91,8 +91,8 @@ static void DragonSeek (AActor *actor, DAngle thresh, DAngle turnMax)
if (actor->target && pr_dragonseek() < 200) if (actor->target && pr_dragonseek() < 200)
{ {
AActor *bestActor = NULL; AActor *bestActor = NULL;
bestAngle = ANGLE_MAX; bestAngle = 360.;
angleToTarget = actor->__f_AngleTo(actor->target); angleToTarget = actor->AngleTo(actor->target);
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
{ {
if (!target->args[i]) if (!target->args[i])
@ -105,10 +105,11 @@ static void DragonSeek (AActor *actor, DAngle thresh, DAngle turnMax)
{ {
continue; continue;
} }
angleToSpot = actor->__f_AngleTo(mo); angleToSpot = actor->AngleTo(mo);
if (absangle(angleToSpot-angleToTarget) < bestAngle) DAngle diff = absangle(angleToSpot, angleToTarget);
if (diff < bestAngle)
{ {
bestAngle = absangle(angleToSpot-angleToTarget); bestAngle = diff;
bestActor = mo; bestActor = mo;
} }
} }
@ -176,7 +177,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
angle_t angle; DAngle angle;
DragonSeek (self, 4., 8.); DragonSeek (self, 4., 8.);
if (self->target) if (self->target)
@ -186,15 +187,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
self->target = NULL; self->target = NULL;
return 0; return 0;
} }
angle = self->__f_AngleTo(self->target); angle = absangle(self->Angles.Yaw, self->AngleTo(self->target));
if (absangle(self->_f_angle()-angle) < ANGLE_45/2 && self->CheckMeleeRange()) if (angle <22.5 && self->CheckMeleeRange())
{ {
int damage = pr_dragonflight.HitDice (8); int damage = pr_dragonflight.HitDice (8);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
} }
else if (absangle(self->_f_angle()-angle) <= ANGLE_1*20) else if (angle <= 20)
{ {
self->SetState (self->MissileState); self->SetState (self->MissileState);
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
@ -260,9 +261,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFX2)
delay = 16+(pr_dragonfx2()>>3); delay = 16+(pr_dragonfx2()>>3);
for (i = 1+(pr_dragonfx2()&3); i; i--) for (i = 1+(pr_dragonfx2()&3); i; i--)
{ {
fixed_t xo = ((pr_dragonfx2() - 128) << 14); double xo = (pr_dragonfx2() - 128) / 4.;
fixed_t yo = ((pr_dragonfx2() - 128) << 14); double yo = (pr_dragonfx2() - 128) / 4.;
fixed_t zo = ((pr_dragonfx2() - 128) << 12); double zo = (pr_dragonfx2() - 128) / 16.;
mo = Spawn ("DragonExplosion", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); mo = Spawn ("DragonExplosion", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo) if (mo)

View file

@ -94,7 +94,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordAttack)
} }
P_SpawnPlayerMissile (self, 0, 0, -10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45./4)); P_SpawnPlayerMissile (self, 0, 0, -10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45./4));
P_SpawnPlayerMissile (self, 0, 0, -5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45./8)); P_SpawnPlayerMissile (self, 0, 0, -5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45./8));
P_SpawnPlayerMissile (self, 0, 0, 0, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw); P_SpawnPlayerMissile (self, 0, 0, 0, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw);
P_SpawnPlayerMissile (self, 0, 0, 5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45./8)); P_SpawnPlayerMissile (self, 0, 0, 5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45./8));
P_SpawnPlayerMissile (self, 0, 0, 10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45./4)); P_SpawnPlayerMissile (self, 0, 0, 10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45./4));
S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM);
@ -115,9 +115,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordFlames)
for (i = 1+(pr_fswordflame()&3); i; i--) for (i = 1+(pr_fswordflame()&3); i; i--)
{ {
fixed_t xo = ((pr_fswordflame() - 128) << 12); double xo = (pr_fswordflame() - 128) / 16.;
fixed_t yo = ((pr_fswordflame() - 128) << 12); double yo = (pr_fswordflame() - 128) / 16.;
fixed_t zo = ((pr_fswordflame() - 128) << 11); double zo = (pr_fswordflame() - 128) / 8.;
Spawn ("FSwordFlame", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); Spawn ("FSwordFlame", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
} }
return 0; return 0;
@ -135,13 +135,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FighterAttack)
if (!self->target) return 0; if (!self->target) return 0;
angle_t angle = self->_f_angle(); P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45. / 4), 0);
P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45. / 8), 0);
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle+ANG45/4, 0); P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw, 0);
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle+ANG45/8, 0); P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45. / 8), 0);
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle, 0); P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45. / 4), 0);
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle-ANG45/8, 0);
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle-ANG45/4, 0);
S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM);
return 0; return 0;
} }

View file

@ -9,7 +9,7 @@
#include "thingdef/thingdef.h" #include "thingdef/thingdef.h"
*/ */
#define FIREDEMON_ATTACK_RANGE 64*8*FRACUNIT #define FIREDEMON_ATTACK_RANGE (64*8.)
static FRandom pr_firedemonrock ("FireDemonRock"); static FRandom pr_firedemonrock ("FireDemonRock");
static FRandom pr_smbounce ("SMBounce"); static FRandom pr_smbounce ("SMBounce");
@ -54,9 +54,9 @@ void A_FiredSpawnRock (AActor *actor)
break; break;
} }
fixed_t xo = ((pr_firedemonrock() - 128) << 12); double xo = (pr_firedemonrock() - 128) / 16.;
fixed_t yo = ((pr_firedemonrock() - 128) << 12); double yo = (pr_firedemonrock() - 128) / 16.;
fixed_t zo = (pr_firedemonrock() << 11); double zo = pr_firedemonrock() / 32.;
mo = Spawn (rtype, actor->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); mo = Spawn (rtype, actor->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo) if (mo)
{ {
@ -138,13 +138,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
int weaveindex = self->special1; int weaveindex = self->special1;
AActor *target = self->target; AActor *target = self->target;
DAngle ang; DAngle ang;
fixed_t dist; double dist;
if (self->reactiontime) self->reactiontime--; if (self->reactiontime) self->reactiontime--;
if (self->threshold) self->threshold--; if (self->threshold) self->threshold--;
// Float up and down // Float up and down
self->_f_AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8); self->AddZ(BobSin(weaveindex));
self->special1 = (weaveindex + 2) & 63; self->special1 = (weaveindex + 2) & 63;
// Ensure it stays above certain height // Ensure it stays above certain height
@ -168,7 +168,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
{ {
self->special2 = 0; self->special2 = 0;
self->Vel.X = self->Vel.Y = 0; self->Vel.X = self->Vel.Y = 0;
dist = self->AproxDistance (target); dist = self->Distance2D(target);
if (dist < FIREDEMON_ATTACK_RANGE) if (dist < FIREDEMON_ATTACK_RANGE)
{ {
if (pr_firedemonchase() < 30) if (pr_firedemonchase() < 30)

View file

@ -67,10 +67,7 @@ IMPLEMENT_CLASS (AArtiPoisonBag2)
bool AArtiPoisonBag2::Use (bool pickup) bool AArtiPoisonBag2::Use (bool pickup)
{ {
angle_t angle = Owner->_f_angle() >> ANGLETOFINESHIFT; AActor *mo = Spawn("FireBomb", Owner->Vec3Offset(
AActor *mo;
mo = Spawn("FireBomb", Owner->Vec3Offset(
16 * Owner->Angles.Yaw.Cos(), 16 * Owner->Angles.Yaw.Cos(),
24 * Owner->Angles.Yaw.Sin(), 24 * Owner->Angles.Yaw.Sin(),
-Owner->Floorclip + 8), ALLOW_REPLACE); -Owner->Floorclip + 8), ALLOW_REPLACE);
@ -97,7 +94,7 @@ bool AArtiPoisonBag3::Use (bool pickup)
{ {
AActor *mo; AActor *mo;
mo = Spawn("ThrowingBomb", Owner->PosPlusZ(-Owner->_f_floorclip()+35*FRACUNIT + (Owner->player? Owner->player->crouchoffset : 0)), ALLOW_REPLACE); mo = Spawn("ThrowingBomb", Owner->PosPlusZ(-Owner->Floorclip+35. + FIXED2FLOAT(Owner->player? Owner->player->crouchoffset : 0)), ALLOW_REPLACE);
if (mo) if (mo)
{ {
mo->Angles.Yaw = Owner->Angles.Yaw + (((pr_poisonbag() & 7) - 4) * (360./256.)); mo->Angles.Yaw = Owner->Angles.Yaw + (((pr_poisonbag() & 7) - 4) * (360./256.));
@ -324,7 +321,7 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
} }
else else
{ {
dopoison = victim->player->poisoncount < (int)(4.f * level.teamdamage); dopoison = victim->player->poisoncount < (int)(4. * level.teamdamage);
} }
if (dopoison) if (dopoison)
@ -332,7 +329,7 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
int damage = 15 + (pr_poisoncloudd()&15); int damage = 15 + (pr_poisoncloudd()&15);
if (mate) if (mate)
{ {
damage = (int)((double)damage * level.teamdamage); damage = (int)(damage * level.teamdamage);
} }
// Handle passive damage modifiers (e.g. PowerProtection) // Handle passive damage modifiers (e.g. PowerProtection)
if (victim->Inventory != NULL) if (victim->Inventory != NULL)
@ -376,7 +373,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagInit)
AActor *mo; AActor *mo;
mo = Spawn<APoisonCloud> (self->PosPlusZ(28*FRACUNIT), ALLOW_REPLACE); mo = Spawn<APoisonCloud> (self->PosPlusZ(28.), ALLOW_REPLACE);
if (mo) if (mo)
{ {
mo->target = self->target; mo->target = self->target;
@ -419,7 +416,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage)
P_RadiusAttack (self, self->target, 4, 40, self->DamageType, RADF_HURTSOURCE); P_RadiusAttack (self, self->target, 4, 40, self->DamageType, RADF_HURTSOURCE);
bobIndex = self->special2; bobIndex = self->special2;
self->_f_AddZ(finesine[bobIndex << BOBTOFINESHIFT] >> 1); self->AddZ(BobSin(bobIndex) / 16);
self->special2 = (bobIndex + 1) & 63; self->special2 = (bobIndex + 1) & 63;
return 0; return 0;
} }

View file

@ -86,9 +86,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlyBuzz)
self->Angles.Yaw = self->AngleTo(targ); self->Angles.Yaw = self->AngleTo(targ);
self->args[0]++; self->args[0]++;
angle_t ang = self->__f_AngleTo(targ); if (!P_TryMove(self, self->Pos().XY() + self->Angles.Yaw.ToVector(6), true))
ang >>= ANGLETOFINESHIFT;
if (!P_TryMove(self, self->_f_X() + 6 * finecosine[ang], self->_f_Y() + 6 * finesine[ang], true))
{ {
self->SetIdle(true); self->SetIdle(true);
return 0; return 0;

View file

@ -15,7 +15,7 @@ static FRandom pr_fogspawn ("FogSpawn");
// args[3] Lifetime countdown // args[3] Lifetime countdown
// args[4] Boolean: fog moving? // args[4] Boolean: fog moving?
// special1 Internal: Counter for spawn frequency // special1 Internal: Counter for spawn frequency
// special2 Internal: Index into floatbob table // WeaveIndexZ Internal: Index into floatbob table
// //
//========================================================================== //==========================================================================
@ -57,7 +57,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn)
mo->args[0] = (pr_fogspawn() % (self->args[0]))+1; // Random speed mo->args[0] = (pr_fogspawn() % (self->args[0]))+1; // Random speed
mo->args[3] = self->args[3]; // Set lifetime mo->args[3] = self->args[3]; // Set lifetime
mo->args[4] = 1; // Set to moving mo->args[4] = 1; // Set to moving
mo->special2 = pr_fogspawn()&63; mo->WeaveIndexZ = pr_fogspawn()&63;
} }
return 0; return 0;
} }
@ -72,7 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
int speed = self->args[0]<<FRACBITS; double speed = self->args[0];
int weaveindex; int weaveindex;
if (!self->args[4]) if (!self->args[4])
@ -88,9 +88,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
if ((self->args[3] % 4) == 0) if ((self->args[3] % 4) == 0)
{ {
weaveindex = self->special2; weaveindex = self->WeaveIndexZ;
self->_f_AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 4); self->AddZ(BobSin(weaveindex) / 2);
self->special2 = (weaveindex + 1) & 63; self->WeaveIndexZ = (weaveindex + 1) & 63;
} }
self->VelFromAngle(speed); self->VelFromAngle(speed);

View file

@ -12,7 +12,7 @@
#include "doomstat.h" #include "doomstat.h"
*/ */
#define HEAL_RADIUS_DIST 255*FRACUNIT #define HEAL_RADIUS_DIST 255.
static FRandom pr_healradius ("HealRadius"); static FRandom pr_healradius ("HealRadius");
@ -42,7 +42,7 @@ bool AArtiHealingRadius::Use (bool pickup)
if (playeringame[i] && if (playeringame[i] &&
players[i].mo != NULL && players[i].mo != NULL &&
players[i].mo->health > 0 && players[i].mo->health > 0 &&
players[i].mo->AproxDistance (Owner) <= HEAL_RADIUS_DIST) players[i].mo->Distance2D (Owner) <= HEAL_RADIUS_DIST)
{ {
// Q: Is it worth it to make this selectable as a player property? // Q: Is it worth it to make this selectable as a player property?
// A: Probably not - but it sure doesn't hurt. // A: Probably not - but it sure doesn't hurt.

View file

@ -16,7 +16,7 @@
// Sorcerer stuff // Sorcerer stuff
// //
// Sorcerer Variables // Sorcerer Variables
// special1 Angle of ball 1 (all others relative to that) // specialf1 Angle of ball 1 (all others relative to that)
// StopBall which ball to stop at in stop mode (MT_???) // StopBall which ball to stop at in stop mode (MT_???)
// args[0] Defense time // args[0] Defense time
// args[1] Number of full rotations since stopping mode // args[1] Number of full rotations since stopping mode
@ -24,7 +24,7 @@
// args[3] Movement mode (see SORC_ macros) // args[3] Movement mode (see SORC_ macros)
// args[4] Current ball orbit speed // args[4] Current ball orbit speed
// Sorcerer Ball Variables // Sorcerer Ball Variables
// special1 Previous angle of ball (for woosh) // specialf1 Previous angle of ball (for woosh)
// special2 Countdown of rapid fire (FX4) // special2 Countdown of rapid fire (FX4)
//============================================================================ //============================================================================
@ -45,9 +45,9 @@
#define SORC_NORMAL 5 #define SORC_NORMAL 5
#define SORC_FIRING_SPELL 6 #define SORC_FIRING_SPELL 6
#define BALL1_ANGLEOFFSET 0 #define BALL1_ANGLEOFFSET 0.
#define BALL2_ANGLEOFFSET (ANGLE_MAX/3) #define BALL2_ANGLEOFFSET 120.
#define BALL3_ANGLEOFFSET ((ANGLE_MAX/3)*2) #define BALL3_ANGLEOFFSET 240.
void A_SlowBalls (AActor *actor); void A_SlowBalls (AActor *actor);
void A_StopBalls (AActor *actor); void A_StopBalls (AActor *actor);
@ -65,6 +65,7 @@ class AHeresiarch : public AActor
DECLARE_CLASS (AHeresiarch, AActor) DECLARE_CLASS (AHeresiarch, AActor)
public: public:
const PClass *StopBall; const PClass *StopBall;
DAngle BallAngle;
void Serialize (FArchive &arc); void Serialize (FArchive &arc);
void Die (AActor *source, AActor *inflictor, int dmgflags); void Die (AActor *source, AActor *inflictor, int dmgflags);
@ -75,7 +76,7 @@ IMPLEMENT_CLASS (AHeresiarch)
void AHeresiarch::Serialize (FArchive &arc) void AHeresiarch::Serialize (FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize (arc);
arc << StopBall; arc << StopBall << BallAngle;
} }
void AHeresiarch::Die (AActor *source, AActor *inflictor, int dmgflags) void AHeresiarch::Die (AActor *source, AActor *inflictor, int dmgflags)
@ -101,12 +102,13 @@ public:
virtual void DoFireSpell (); virtual void DoFireSpell ();
virtual void SorcUpdateBallAngle (); virtual void SorcUpdateBallAngle ();
virtual void CastSorcererSpell (); virtual void CastSorcererSpell ();
angle_t AngleOffset; DAngle AngleOffset;
DAngle OldAngle;
void Serialize (FArchive &arc) void Serialize (FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize (arc);
arc << AngleOffset; arc << AngleOffset << OldAngle;
} }
bool SpecialBlastHandling (AActor *source, double strength) bool SpecialBlastHandling (AActor *source, double strength)
@ -231,7 +233,7 @@ void ASorcBall1::DoFireSpell ()
DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls) DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE_TYPE(AHeresiarch);
AActor *mo; AActor *mo;
@ -240,7 +242,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
self->args[0] = 0; // Currently no defense self->args[0] = 0; // Currently no defense
self->args[3] = SORC_NORMAL; self->args[3] = SORC_NORMAL;
self->args[4] = SORCBALL_INITIAL_SPEED; // Initial orbit speed self->args[4] = SORCBALL_INITIAL_SPEED; // Initial orbit speed
self->special1 = ANGLE_1; self->BallAngle = 1.;
DVector3 pos = self->PosPlusZ(-self->Floorclip + self->Height); DVector3 pos = self->PosPlusZ(-self->Floorclip + self->Height);
@ -262,11 +264,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
// //
// A_SorcBallOrbit // A_SorcBallOrbit
// //
// - actor is ball
//============================================================================ //============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit) DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE_TYPE(ASorcBall);
// [RH] If no parent, then die instead of crashing // [RH] If no parent, then die instead of crashing
if (self->target == NULL) if (self->target == NULL)
@ -275,78 +278,78 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
return 0; return 0;
} }
ASorcBall *actor;
angle_t angle, baseangle;
int mode = self->target->args[3]; int mode = self->target->args[3];
AHeresiarch *parent = barrier_cast<AHeresiarch *>(self->target); AHeresiarch *parent = barrier_cast<AHeresiarch *>(self->target);
int dist = parent->_f_radius() - (self->_f_radius()<<1); double dist = parent->radius - (self->radius*2);
angle_t prevangle = self->special1;
#if 0
// This cannot happen anymore because this is defined locally in SorcBall
if (!self->IsKindOf (RUNTIME_CLASS(ASorcBall))) if (!self->IsKindOf (RUNTIME_CLASS(ASorcBall)))
{ {
I_Error ("Corrupted sorcerer:\nTried to use a %s", self->GetClass()->TypeName.GetChars()); I_Error ("Corrupted sorcerer:\nTried to use a %s", self->GetClass()->TypeName.GetChars());
} }
actor = static_cast<ASorcBall *> (self); #endif
if (actor->target->health <= 0) if (self->target->health <= 0)
{ {
actor->SetState (actor->FindState(NAME_Pain)); self->SetState (self->FindState(NAME_Pain));
return 0; return 0;
} }
baseangle = (angle_t)parent->special1; DAngle prevangle = self->OldAngle;
angle = baseangle + actor->AngleOffset; DAngle baseangle = parent->BallAngle;
actor->Angles.Yaw = ANGLE2FLOAT(angle); DAngle angle = baseangle + self->AngleOffset;
angle >>= ANGLETOFINESHIFT;
self->Angles.Yaw = angle;
switch (mode) switch (mode)
{ {
case SORC_NORMAL: // Balls rotating normally case SORC_NORMAL: // Balls rotating normally
actor->SorcUpdateBallAngle (); self->SorcUpdateBallAngle ();
break; break;
case SORC_DECELERATE: // Balls decelerating case SORC_DECELERATE: // Balls decelerating
A_DecelBalls(actor); A_DecelBalls(self);
actor->SorcUpdateBallAngle (); self->SorcUpdateBallAngle ();
break; break;
case SORC_ACCELERATE: // Balls accelerating case SORC_ACCELERATE: // Balls accelerating
A_AccelBalls(actor); A_AccelBalls(self);
actor->SorcUpdateBallAngle (); self->SorcUpdateBallAngle ();
break; break;
case SORC_STOPPING: // Balls stopping case SORC_STOPPING: // Balls stopping
if ((parent->StopBall == actor->GetClass()) && if ((parent->StopBall == self->GetClass()) &&
(parent->args[1] > SORCBALL_SPEED_ROTATIONS) && (parent->args[1] > SORCBALL_SPEED_ROTATIONS) &&
(absangle(angle - (parent->_f_angle()>>ANGLETOFINESHIFT)) < (30<<5))) absangle(angle, parent->Angles.Yaw) < 42.1875)
{ {
// Can stop now // Can stop now
actor->target->args[3] = SORC_FIRESPELL; self->target->args[3] = SORC_FIRESPELL;
actor->target->args[4] = 0; self->target->args[4] = 0;
// Set angle so self angle == sorcerer angle // Set angle so self angle == sorcerer angle
parent->special1 = (int)(parent->_f_angle() - actor->AngleOffset); parent->BallAngle = parent->Angles.Yaw - self->AngleOffset;
} }
else else
{ {
actor->SorcUpdateBallAngle (); self->SorcUpdateBallAngle ();
} }
break; break;
case SORC_FIRESPELL: // Casting spell case SORC_FIRESPELL: // Casting spell
if (parent->StopBall == actor->GetClass()) if (parent->StopBall == self->GetClass())
{ {
// Put sorcerer into special throw spell anim // Put sorcerer into special throw spell anim
if (parent->health > 0) if (parent->health > 0)
parent->SetState (parent->FindState("Attack1")); parent->SetState (parent->FindState("Attack1"));
actor->DoFireSpell (); self->DoFireSpell ();
} }
break; break;
case SORC_FIRING_SPELL: case SORC_FIRING_SPELL:
if (parent->StopBall == actor->GetClass()) if (parent->StopBall == self->GetClass())
{ {
if (actor->special2-- <= 0) if (self->special2-- <= 0)
{ {
// Done rapid firing // Done rapid firing
parent->args[3] = SORC_STOPPED; parent->args[3] = SORC_STOPPED;
@ -357,7 +360,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
else else
{ {
// Do rapid fire spell // Do rapid fire spell
A_SorcOffense2(actor); A_SorcOffense2(self);
} }
} }
break; break;
@ -367,21 +370,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
break; break;
} }
if ((angle < prevangle) && (parent->args[4]==SORCBALL_TERMINAL_SPEED)) if (deltaangle(angle, prevangle) < 0 && (parent->args[4]==SORCBALL_TERMINAL_SPEED))
{ {
parent->args[1]++; // Bump rotation counter parent->args[1]++; // Bump rotation counter
// Completed full rotation - make woosh sound // Completed full rotation - make woosh sound
S_Sound (actor, CHAN_BODY, "SorcererBallWoosh", 1, ATTN_NORM); S_Sound (self, CHAN_BODY, "SorcererBallWoosh", 1, ATTN_NORM);
} }
actor->special1 = angle; // Set previous angle self->OldAngle = angle; // Set previous angle
fixedvec3 pos = parent->Vec3Offset( DVector3 pos = parent->Vec3Angle(dist, angle, -parent->Floorclip + parent->Height);
FixedMul(dist, finecosine[angle]), self->SetOrigin (pos, true);
FixedMul(dist, finesine[angle]), self->floorz = parent->floorz;
-parent->_f_floorclip() + parent->_f_height()); self->ceilingz = parent->ceilingz;
actor->SetOrigin (pos, true);
actor->floorz = parent->floorz;
actor->ceilingz = parent->ceilingz;
return 0; return 0;
} }
@ -411,10 +411,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpeedBalls)
// //
//============================================================================ //============================================================================
void A_SlowBalls(AActor *actor) void A_SlowBalls(AActor *self)
{ {
actor->args[3] = SORC_DECELERATE; // slow mode self->args[3] = SORC_DECELERATE; // slow mode
actor->args[2] = SORCBALL_INITIAL_SPEED; // target speed self->args[2] = SORCBALL_INITIAL_SPEED; // target speed
} }
//============================================================================ //============================================================================
@ -428,23 +428,23 @@ void A_SlowBalls(AActor *actor)
void A_StopBalls(AActor *scary) void A_StopBalls(AActor *scary)
{ {
AHeresiarch *actor = static_cast<AHeresiarch *> (scary); AHeresiarch *self = static_cast<AHeresiarch *> (scary);
int chance = pr_heresiarch(); int chance = pr_heresiarch();
actor->args[3] = SORC_STOPPING; // stopping mode self->args[3] = SORC_STOPPING; // stopping mode
actor->args[1] = 0; // Reset rotation counter self->args[1] = 0; // Reset rotation counter
if ((actor->args[0] <= 0) && (chance < 200)) if ((self->args[0] <= 0) && (chance < 200))
{ {
actor->StopBall = RUNTIME_CLASS(ASorcBall2); // Blue self->StopBall = RUNTIME_CLASS(ASorcBall2); // Blue
} }
else if((actor->health < (actor->SpawnHealth() >> 1)) && else if((self->health < (self->SpawnHealth() >> 1)) &&
(chance < 200)) (chance < 200))
{ {
actor->StopBall = RUNTIME_CLASS(ASorcBall3); // Green self->StopBall = RUNTIME_CLASS(ASorcBall3); // Green
} }
else else
{ {
actor->StopBall = RUNTIME_CLASS(ASorcBall1); // Yellow self->StopBall = RUNTIME_CLASS(ASorcBall1); // Yellow
} }
} }
@ -456,9 +456,9 @@ void A_StopBalls(AActor *scary)
// //
//============================================================================ //============================================================================
void A_AccelBalls(AActor *actor) void A_AccelBalls(AActor *self)
{ {
AActor *sorc = actor->target; AActor *sorc = self->target;
if (sorc->args[4] < sorc->args[2]) if (sorc->args[4] < sorc->args[2])
{ {
@ -483,9 +483,9 @@ void A_AccelBalls(AActor *actor)
// //
//============================================================================ //============================================================================
void A_DecelBalls(AActor *actor) void A_DecelBalls(AActor *self)
{ {
AActor *sorc = actor->target; AActor *sorc = self->target;
if (sorc->args[4] > sorc->args[2]) if (sorc->args[4] > sorc->args[2])
{ {
@ -506,7 +506,7 @@ void A_DecelBalls(AActor *actor)
void ASorcBall1::SorcUpdateBallAngle () void ASorcBall1::SorcUpdateBallAngle ()
{ {
target->special1 += ANGLE_1*target->args[4]; barrier_cast<AHeresiarch*>(target)->BallAngle += target->args[4];
} }
//============================================================================ //============================================================================
@ -551,7 +551,7 @@ void ASorcBall2::CastSorcererSpell ()
AActor *parent = target; AActor *parent = target;
AActor *mo; AActor *mo;
mo = Spawn("SorcFX2", PosPlusZ(-parent->_f_floorclip() + SORC_DEFENSE_HEIGHT*FRACUNIT), ALLOW_REPLACE); mo = Spawn("SorcFX2", PosPlusZ(parent->Floorclip + SORC_DEFENSE_HEIGHT), ALLOW_REPLACE);
parent->flags2 |= MF2_REFLECTIVE|MF2_INVULNERABLE; parent->flags2 |= MF2_REFLECTIVE|MF2_INVULNERABLE;
parent->args[0] = SORC_DEFENSE_TIME; parent->args[0] = SORC_DEFENSE_TIME;
if (mo) mo->target = parent; if (mo) mo->target = parent;
@ -570,24 +570,24 @@ void ASorcBall3::CastSorcererSpell ()
Super::CastSorcererSpell (); Super::CastSorcererSpell ();
AActor *mo; AActor *mo;
angle_t ang1, ang2; DAngle ang1, ang2;
AActor *parent = target; AActor *parent = target;
ang1 = FLOAT2ANGLE(Angles.Yaw.Degrees) - ANGLE_45; ang1 = Angles.Yaw.Degrees - 45;
ang2 = FLOAT2ANGLE(Angles.Yaw.Degrees) + ANGLE_45; ang2 = Angles.Yaw.Degrees + 45;
PClassActor *cls = PClass::FindActor("SorcFX3"); PClassActor *cls = PClass::FindActor("SorcFX3");
if (health < (SpawnHealth()/3)) if (health < (SpawnHealth()/3))
{ // Spawn 2 at a time { // Spawn 2 at a time
mo = P_SpawnMissileAngle(parent, cls, ang1, 4*FRACUNIT); mo = P_SpawnMissileAngle(parent, cls, ang1, 4.);
if (mo) mo->target = parent; if (mo) mo->target = parent;
mo = P_SpawnMissileAngle(parent, cls, ang2, 4*FRACUNIT); mo = P_SpawnMissileAngle(parent, cls, ang2, 4.);
if (mo) mo->target = parent; if (mo) mo->target = parent;
} }
else else
{ {
if (pr_heresiarch() < 128) if (pr_heresiarch() < 128)
ang1 = ang2; ang1 = ang2;
mo = P_SpawnMissileAngle(parent, cls, ang1, 4*FRACUNIT); mo = P_SpawnMissileAngle(parent, cls, ang1, 4.);
if (mo) mo->target = parent; if (mo) mo->target = parent;
} }
} }
@ -596,12 +596,12 @@ void ASorcBall3::CastSorcererSpell ()
/* /*
void A_SpawnReinforcements(AActor *actor) void A_SpawnReinforcements(AActor *actor)
{ {
AActor *parent = actor->target; AActor *parent = self->target;
AActor *mo; AActor *mo;
angle_t ang; DAngle ang;
ang = ANGLE_1 * P_Random(); ang = P_Random();
mo = P_SpawnMissileAngle(actor, MT_SORCFX3, ang, 5*FRACUNIT); mo = P_SpawnMissileAngle(actor, MT_SORCFX3, ang, 5.);
if (mo) mo->target = parent; if (mo) mo->target = parent;
} }
*/ */
@ -619,11 +619,11 @@ void ASorcBall1::CastSorcererSpell ()
Super::CastSorcererSpell (); Super::CastSorcererSpell ();
AActor *mo; AActor *mo;
angle_t ang1, ang2; DAngle ang1, ang2;
AActor *parent = target; AActor *parent = target;
ang1 = FLOAT2ANGLE(Angles.Yaw.Degrees) + ANGLE_1*70; ang1 = Angles.Yaw.Degrees + 70;
ang2 = FLOAT2ANGLE(Angles.Yaw.Degrees) - ANGLE_1*70; ang2 = Angles.Yaw.Degrees - 70;
PClassActor *cls = PClass::FindActor("SorcFX1"); PClassActor *cls = PClass::FindActor("SorcFX1");
mo = P_SpawnMissileAngle (parent, cls, ang1, 0); mo = P_SpawnMissileAngle (parent, cls, ang1, 0);
if (mo) if (mo)
@ -651,12 +651,13 @@ void ASorcBall1::CastSorcererSpell ()
// //
//============================================================================ //============================================================================
void A_SorcOffense2(AActor *actor) void A_SorcOffense2(AActor *self)
{ {
angle_t ang1; DAngle ang1;
AActor *mo; AActor *mo;
int delta, index; double delta;
AActor *parent = actor->target; int index;
AActor *parent = self->target;
AActor *dest = parent->target; AActor *dest = parent->target;
double dist; double dist;
@ -666,11 +667,11 @@ void A_SorcOffense2(AActor *actor)
return; return;
} }
index = actor->args[4] << 5; index = self->args[4];
actor->args[4] = (actor->args[4] + 15) & 255; self->args[4] = (self->args[4] + 15) & 255;
delta = (finesine[index])*SORCFX4_SPREAD_ANGLE; delta = DAngle(index * (360 / 256.f)).Sin() * SORCFX4_SPREAD_ANGLE;
delta = (delta>>FRACBITS)*ANGLE_1;
ang1 = actor->_f_angle() + delta; ang1 = self->Angles.Yaw + delta;
mo = P_SpawnMissileAngle(parent, PClass::FindActor("SorcFX4"), ang1, 0); mo = P_SpawnMissileAngle(parent, PClass::FindActor("SorcFX4"), ang1, 0);
if (mo) if (mo)
{ {
@ -708,13 +709,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBossAttack)
DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle) DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
fixed_t dist = 5*FRACUNIT;
int speed = (int)self->Speed; int speed = (int)self->Speed;
DAngle rangle; DAngle rangle;
AActor *mo; AActor *mo;
int ix; int ix;
fixedvec3 pos = self->_f_Vec3Angle(dist, self->_f_angle(), -self->_f_floorclip() + (self->_f_height() >> 1)); DVector3 pos = self->Vec3Angle(5., self->Angles.Yaw, -self->Floorclip + self->Height / 2. );
for (ix=0; ix<5; ix++) for (ix=0; ix<5; ix++)
{ {
mo = Spawn("SorcSpark1", pos, ALLOW_REPLACE); mo = Spawn("SorcSpark1", pos, ALLOW_REPLACE);
@ -743,7 +743,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX1Seek)
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
A_DoBounceCheck (self, "SorcererHeadScream"); A_DoBounceCheck (self, "SorcererHeadScream");
P_SeekerMissile (self,ANGLE_1*2,ANGLE_1*6); P_SeekerMissile(self, 2, 6);
return 0; return 0;
} }
@ -757,7 +757,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX1Seek)
//============================================================================ //============================================================================
// //
// FX2 Variables // FX2 Variables
// special1 current angle // specialf1 current angle
// special2 // special2
// args[0] 0 = CW, 1 = CCW // args[0] 0 = CW, 1 = CCW
// args[1] // args[1]
@ -775,7 +775,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split)
{ {
mo->target = self->target; mo->target = self->target;
mo->args[0] = 0; // CW mo->args[0] = 0; // CW
mo->special1 = self->_f_angle(); // Set angle mo->specialf1 = self->Angles.Yaw.Degrees; // Set angle
mo->SetState (mo->FindState("Orbit")); mo->SetState (mo->FindState("Orbit"));
} }
mo = Spawn(self->GetClass(), self->Pos(), NO_REPLACE); mo = Spawn(self->GetClass(), self->Pos(), NO_REPLACE);
@ -783,7 +783,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split)
{ {
mo->target = self->target; mo->target = self->target;
mo->args[0] = 1; // CCW mo->args[0] = 1; // CCW
mo->special1 = self->_f_angle(); // Set angle mo->specialf1 = self->Angles.Yaw.Degrees; // Set angle
mo->SetState (mo->FindState("Orbit")); mo->SetState (mo->FindState("Orbit"));
} }
self->Destroy (); self->Destroy ();
@ -802,8 +802,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
angle_t angle; DAngle angle;
fixedvec3 pos; DVector3 pos;
AActor *parent = self->target; AActor *parent = self->target;
// [RH] If no parent, then disappear // [RH] If no parent, then disappear
@ -813,7 +813,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
return 0; return 0;
} }
fixed_t dist = parent->_f_radius(); double dist = parent->radius;
if ((parent->health <= 0) || // Sorcerer is dead if ((parent->health <= 0) || // Sorcerer is dead
(!parent->args[0])) // Time expired (!parent->args[0])) // Time expired
@ -834,25 +834,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
// Move to new position based on angle // Move to new position based on angle
if (self->args[0]) // Counter clock-wise if (self->args[0]) // Counter clock-wise
{ {
self->special1 += ANGLE_1*10; self->specialf1 += 10;
angle = ((angle_t)self->special1) >> ANGLETOFINESHIFT; angle = self->specialf1;
pos = parent->Vec3Offset( pos = parent->Vec3Angle(dist, angle, parent->Floorclip + SORC_DEFENSE_HEIGHT);
FixedMul(dist, finecosine[angle]), pos.Z += 15 * angle.Cos();
FixedMul(dist, finesine[angle]),
parent->_f_floorclip() + SORC_DEFENSE_HEIGHT*FRACUNIT);
pos.z += FixedMul(15*FRACUNIT,finecosine[angle]);
// Spawn trailer // Spawn trailer
Spawn("SorcFX2T1", pos, ALLOW_REPLACE); Spawn("SorcFX2T1", pos, ALLOW_REPLACE);
} }
else // Clock wise else // Clock wise
{ {
self->special1 -= ANGLE_1*10; self->specialf1 -= 10;
angle = ((angle_t)self->special1) >> ANGLETOFINESHIFT; pos = parent->Vec3Angle(dist, angle, parent->Floorclip + SORC_DEFENSE_HEIGHT);
pos = parent->Vec3Offset( pos.Z += 20 * angle.Sin();
FixedMul(dist, finecosine[angle]),
FixedMul(dist, finesine[angle]),
parent->_f_floorclip() + SORC_DEFENSE_HEIGHT*FRACUNIT);
pos.z += FixedMul(20*FRACUNIT,finesine[angle]);
// Spawn trailer // Spawn trailer
Spawn("SorcFX2T1", pos, ALLOW_REPLACE); Spawn("SorcFX2T1", pos, ALLOW_REPLACE);
} }
@ -947,7 +940,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallPop)
self->Vel.X = ((pr_heresiarch()%10)-5); self->Vel.X = ((pr_heresiarch()%10)-5);
self->Vel.Y = ((pr_heresiarch()%10)-5); self->Vel.Y = ((pr_heresiarch()%10)-5);
self->Vel.Z = (2+(pr_heresiarch()%3)); self->Vel.Z = (2+(pr_heresiarch()%3));
self->special2 = 4*FRACUNIT; // Initial bounce factor
self->args[4] = BOUNCE_TIME_UNIT; // Bounce time unit self->args[4] = BOUNCE_TIME_UNIT; // Bounce time unit
self->args[3] = 5; // Bounce time in seconds self->args[3] = 5; // Bounce time in seconds
return 0; return 0;

View file

@ -117,7 +117,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryCheck)
if (playeringame[i]) if (playeringame[i])
{ {
AActor *pmo = players[i].mo; AActor *pmo = players[i].mo;
if (P_CheckSight (self, pmo) && (absangle(pmo->__f_AngleTo(self) - pmo->_f_angle()) <= ANGLE_45)) if (P_CheckSight (self, pmo) && (absangle(pmo->AngleTo(self), pmo->Angles.Yaw) <= 45))
{ // Previous state (pottery bit waiting state) { // Previous state (pottery bit waiting state)
self->SetState (self->state - 1); self->SetState (self->state - 1);
return 0; return 0;
@ -156,7 +156,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseBloodDrip)
if (pr_drip() <= 128) if (pr_drip() <= 128)
{ {
Spawn ("CorpseBloodDrip", self->PosPlusZ(self->_f_height()/2), ALLOW_REPLACE); Spawn ("CorpseBloodDrip", self->PosPlusZ(self->Height / 2), ALLOW_REPLACE);
} }
return 0; return 0;
} }
@ -186,7 +186,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode)
} }
} }
// Spawn a skull // Spawn a skull
mo = Spawn ("CorpseBit", self->_f_Pos(), ALLOW_REPLACE); mo = Spawn ("CorpseBit", self->Pos(), ALLOW_REPLACE);
if (mo) if (mo)
{ {
mo->SetState (mo->SpawnState + 3); mo->SetState (mo->SpawnState + 3);
@ -214,9 +214,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
for (i = (pr_leaf()&3)+1; i; i--) for (i = (pr_leaf()&3)+1; i; i--)
{ {
fixed_t xo = (pr_leaf.Random2() << 14); double xo = pr_leaf.Random2() / 4.;
fixed_t yo = (pr_leaf.Random2() << 14); double yo = pr_leaf.Random2() / 4.;
fixed_t zo = (pr_leaf() << 14); double zo = pr_leaf() / 4.;
mo = Spawn (pr_leaf()&1 ? PClass::FindActor ("Leaf1") : PClass::FindActor ("Leaf2"), mo = Spawn (pr_leaf()&1 ? PClass::FindActor ("Leaf1") : PClass::FindActor ("Leaf2"),
self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
@ -289,7 +289,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonShroom)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
self->tics = 128+(pr_shroom()<<1); self->tics = 128 + (pr_shroom() << 1);
return 0; return 0;
} }
@ -308,9 +308,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode)
for (i = 0; i < 10; i++) for (i = 0; i < 10; i++)
{ {
fixed_t xo = ((pr_soaexplode() - 128) << 12); double xo = (pr_soaexplode() - 128) / 16.;
fixed_t yo = ((pr_soaexplode() - 128) << 12); double yo = (pr_soaexplode() - 128) / 16.;
fixed_t zo = (pr_soaexplode()*self->_f_height() / 256); double zo = pr_soaexplode()*self->Height / 256.;
mo = Spawn ("ZArmorChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); mo = Spawn ("ZArmorChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo) if (mo)
{ {

View file

@ -28,19 +28,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
fixed_t dist; double dist;
fixed_t an; DAngle an;
CALL_ACTION(A_Look, self); CALL_ACTION(A_Look, self);
if (pr_iceguylook() < 64) if (pr_iceguylook() < 64)
{ {
dist = ((pr_iceguylook()-128)*self->_f_radius())>>7; dist = (pr_iceguylook() - 128) * self->radius / 128.;
an = (self->_f_angle()+ANG90)>>ANGLETOFINESHIFT; an = self->Angles.Yaw + 90;
Spawn(WispTypes[pr_iceguylook() & 1], self->Vec3Angle(dist, an, 60.), ALLOW_REPLACE);
Spawn(WispTypes[pr_iceguylook() & 1], self->Vec3Offset(
FixedMul(dist, finecosine[an]),
FixedMul(dist, finesine[an]),
60 * FRACUNIT), ALLOW_REPLACE);
} }
return 0; return 0;
} }
@ -55,20 +51,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
fixed_t dist; double dist;
fixed_t an; DAngle an;
AActor *mo; AActor *mo;
A_Chase (stack, self); A_Chase(stack, self);
if (pr_iceguychase() < 128) if (pr_iceguychase() < 128)
{ {
dist = ((pr_iceguychase()-128)*self->_f_radius())>>7; dist = (pr_iceguychase() - 128) * self->radius / 128.;
an = (self->_f_angle()+ANG90)>>ANGLETOFINESHIFT; an = self->Angles.Yaw + 90;
mo = Spawn(WispTypes[pr_iceguylook() & 1], self->Vec3Angle(dist, an, 60.), ALLOW_REPLACE);
mo = Spawn(WispTypes[pr_iceguychase() & 1], self->Vec3Offset(
FixedMul(dist, finecosine[an]),
FixedMul(dist, finesine[an]),
60 * FRACUNIT), ALLOW_REPLACE);
if (mo) if (mo)
{ {
mo->Vel = self->Vel; mo->Vel = self->Vel;
@ -92,8 +84,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyAttack)
{ {
return 0; return 0;
} }
P_SpawnMissileXYZ(self->_f_Vec3Angle(self->_f_radius()>>1, self->_f_angle()+ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX")); P_SpawnMissileXYZ(self->Vec3Angle(self->radius / 2, self->Angles.Yaw + 90, 40.), self, self->target, PClass::FindActor("IceGuyFX"));
P_SpawnMissileXYZ(self->_f_Vec3Angle(self->_f_radius()>>1, self->_f_angle()-ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX")); P_SpawnMissileXYZ(self->Vec3Angle(self->radius / 2, self->Angles.Yaw - 90, 40.), self, self->target, PClass::FindActor("IceGuyFX"));
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
return 0; return 0;
} }
@ -129,8 +121,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyMissileExplode)
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
mo = P_SpawnMissileAngleZ (self, self->_f_Z()+3*FRACUNIT, mo = P_SpawnMissileAngleZ (self, self->Z()+3, PClass::FindActor("IceGuyFX2"), DAngle(i*45.), -0.3);
PClass::FindActor("IceGuyFX2"), i*ANG45, (fixed_t)(-0.3*FRACUNIT));
if (mo) if (mo)
{ {
mo->target = self->target; mo->target = self->target;

View file

@ -37,16 +37,16 @@ const int KORAX_TID = 245;
const int KORAX_FIRST_TELEPORT_TID = 248; const int KORAX_FIRST_TELEPORT_TID = 248;
const int KORAX_TELEPORT_TID = 249; const int KORAX_TELEPORT_TID = 249;
const int KORAX_DELTAANGLE = 85*ANGLE_1; const int KORAX_DELTAANGLE = 85;
const int KORAX_ARM_EXTENSION_SHORT = 40; const int KORAX_ARM_EXTENSION_SHORT = 40;
const int KORAX_ARM_EXTENSION_LONG = 55; const int KORAX_ARM_EXTENSION_LONG = 55;
const int KORAX_ARM1_HEIGHT = 108*FRACUNIT; const int KORAX_ARM1_HEIGHT = 108;
const int KORAX_ARM2_HEIGHT = 82*FRACUNIT; const int KORAX_ARM2_HEIGHT = 82;
const int KORAX_ARM3_HEIGHT = 54*FRACUNIT; const int KORAX_ARM3_HEIGHT = 54;
const int KORAX_ARM4_HEIGHT = 104*FRACUNIT; const int KORAX_ARM4_HEIGHT = 104;
const int KORAX_ARM5_HEIGHT = 86*FRACUNIT; const int KORAX_ARM5_HEIGHT = 86;
const int KORAX_ARM6_HEIGHT = 53*FRACUNIT; const int KORAX_ARM6_HEIGHT = 53;
const double KORAX_BOLT_HEIGHT = 48.; const double KORAX_BOLT_HEIGHT = 48.;
const int KORAX_BOLT_LIFETIME = 3; const int KORAX_BOLT_LIFETIME = 3;
@ -76,8 +76,7 @@ void A_KBoltRaise (AActor *);
void KoraxFire (AActor *actor, PClassActor *type, int arm); void KoraxFire (AActor *actor, PClassActor *type, int arm);
void KSpiritInit (AActor *spirit, AActor *korax); void KSpiritInit (AActor *spirit, AActor *korax);
AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z, AActor *P_SpawnKoraxMissile (const DVector3 &pos, AActor *source, AActor *dest, PClassActor *type);
AActor *source, AActor *dest, PClassActor *type);
extern void SpawnSpiritTail (AActor *spirit); extern void SpawnSpiritTail (AActor *spirit);
@ -99,7 +98,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
spot = iterator.Next (); spot = iterator.Next ();
if (spot != NULL) if (spot != NULL)
{ {
P_Teleport (self, spot->_f_X(), spot->_f_Y(), ONFLOORZ, spot->Angles.Yaw, TELF_SOURCEFOG | TELF_DESTFOG); P_Teleport (self, spot->PosAtZ(ONFLOORZ), spot->Angles.Yaw, TELF_SOURCEFOG | TELF_DESTFOG);
} }
P_StartScript (self, NULL, 249, NULL, NULL, 0, 0); P_StartScript (self, NULL, 249, NULL, NULL, 0, 0);
@ -141,7 +140,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
self->tracer = spot; self->tracer = spot;
if (spot) if (spot)
{ {
P_Teleport (self, spot->_f_X(), spot->_f_Y(), ONFLOORZ, spot->Angles.Yaw, TELF_SOURCEFOG | TELF_DESTFOG); P_Teleport (self, spot->PosAtZ(ONFLOORZ), spot->Angles.Yaw, TELF_SOURCEFOG | TELF_DESTFOG);
} }
} }
} }
@ -164,7 +163,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxBonePop)
// Spawn 6 spirits equalangularly // Spawn 6 spirits equalangularly
for (i = 0; i < 6; ++i) for (i = 0; i < 6; ++i)
{ {
mo = P_SpawnMissileAngle (self, PClass::FindActor("KoraxSpirit"), ANGLE_60*i, 5*FRACUNIT); mo = P_SpawnMissileAngle (self, PClass::FindActor("KoraxSpirit"), DAngle(60.*i), 5.);
if (mo) if (mo)
{ {
KSpiritInit (mo, self); KSpiritInit (mo, self);
@ -186,7 +185,7 @@ void KSpiritInit (AActor *spirit, AActor *korax)
spirit->health = KORAX_SPIRIT_LIFETIME; spirit->health = KORAX_SPIRIT_LIFETIME;
spirit->tracer = korax; // Swarm around korax spirit->tracer = korax; // Swarm around korax
spirit->special2 = FINEANGLES/2 + pr_kspiritinit(8 << BOBTOFINESHIFT); // Float bob index spirit->WeaveIndexZ = 32 + (pr_kspiritinit() & 7); // Float bob index
spirit->args[0] = 10; // initial turn value spirit->args[0] = 10; // initial turn value
spirit->args[1] = 0; // initial look angle spirit->args[1] = 0; // initial look angle
@ -235,23 +234,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
{ "SerpentFX", "CentaurLeaderAttack" } { "SerpentFX", "CentaurLeaderAttack" }
}; };
int type = pr_koraxmissile()%6; int type = pr_koraxmissile() % 6;
int i; int i;
PClassActor *info; PClassActor *info;
S_Sound (self, CHAN_VOICE, "KoraxAttack", 1, ATTN_NORM); S_Sound(self, CHAN_VOICE, "KoraxAttack", 1, ATTN_NORM);
info = PClass::FindActor(choices[type].type); info = PClass::FindActor(choices[type].type);
if (info == NULL) if (info == NULL)
{ {
I_Error ("Unknown Korax missile: %s\n", choices[type].type); I_Error("Unknown Korax missile: %s\n", choices[type].type);
} }
// Fire all 6 missiles at once // Fire all 6 missiles at once
S_Sound (self, CHAN_WEAPON, choices[type].sound, 1, ATTN_NONE); S_Sound(self, CHAN_WEAPON, choices[type].sound, 1, ATTN_NONE);
for (i = 0; i < 6; ++i) for (i = 0; i < 6; ++i)
{ {
KoraxFire (self, info, i); KoraxFire(self, info, i);
} }
return 0; return 0;
} }
@ -267,17 +266,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand) DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
angle_t ang; DAngle ang;
int numcommands; int numcommands;
S_Sound (self, CHAN_VOICE, "KoraxCommand", 1, ATTN_NORM); S_Sound (self, CHAN_VOICE, "KoraxCommand", 1, ATTN_NORM);
// Shoot stream of lightning to ceiling // Shoot stream of lightning to ceiling
ang = (self->_f_angle() - ANGLE_90) >> ANGLETOFINESHIFT; ang = self->Angles.Yaw - 90;
fixedvec3 pos = self->Vec3Offset( DVector3 pos = self->Vec3Angle(KORAX_COMMAND_OFFSET, ang, KORAX_COMMAND_HEIGHT);
KORAX_COMMAND_OFFSET * finecosine[ang],
KORAX_COMMAND_OFFSET * finesine[ang],
KORAX_COMMAND_HEIGHT*FRACUNIT);
Spawn("KoraxBolt", pos, ALLOW_REPLACE); Spawn("KoraxBolt", pos, ALLOW_REPLACE);
if (self->health <= (self->SpawnHealth() >> 1)) if (self->health <= (self->SpawnHealth() >> 1))
@ -319,7 +315,7 @@ void KoraxFire (AActor *actor, PClassActor *type, int arm)
KORAX_ARM_EXTENSION_LONG, KORAX_ARM_EXTENSION_LONG,
KORAX_ARM_EXTENSION_LONG KORAX_ARM_EXTENSION_LONG
}; };
static const fixed_t armheight[6] = static const int armheight[6] =
{ {
KORAX_ARM1_HEIGHT, KORAX_ARM1_HEIGHT,
KORAX_ARM2_HEIGHT, KORAX_ARM2_HEIGHT,
@ -329,14 +325,9 @@ void KoraxFire (AActor *actor, PClassActor *type, int arm)
KORAX_ARM6_HEIGHT KORAX_ARM6_HEIGHT
}; };
angle_t ang; DAngle ang = actor->Angles.Yaw + (arm < 3 ? -KORAX_DELTAANGLE : KORAX_DELTAANGLE);
DVector3 pos = actor->Vec3Angle(extension[arm], ang, armheight[arm] - actor->Floorclip);
ang = (actor->_f_angle() + (arm < 3 ? -KORAX_DELTAANGLE : KORAX_DELTAANGLE)) >> ANGLETOFINESHIFT; P_SpawnKoraxMissile (pos, actor, actor->target, type);
fixedvec3 pos = actor->Vec3Offset(
extension[arm] * finecosine[ang],
extension[arm] * finesine[ang],
-actor->_f_floorclip() + armheight[arm]);
P_SpawnKoraxMissile (pos.x, pos.y, pos.z, actor, actor->target, type);
} }
//============================================================================ //============================================================================
@ -348,11 +339,10 @@ void KoraxFire (AActor *actor, PClassActor *type, int arm)
static void A_KSpiritSeeker (AActor *actor, DAngle thresh, DAngle turnMax) static void A_KSpiritSeeker (AActor *actor, DAngle thresh, DAngle turnMax)
{ {
int dir; int dir;
int dist;
DAngle delta; DAngle delta;
AActor *target; AActor *target;
fixed_t newZ; double newZ;
fixed_t deltaZ; double deltaZ;
target = actor->tracer; target = actor->tracer;
if (target == NULL) if (target == NULL)
@ -379,28 +369,24 @@ static void A_KSpiritSeeker (AActor *actor, DAngle thresh, DAngle turnMax)
actor->VelFromAngle(); actor->VelFromAngle();
if (!(level.time&15) if (!(level.time&15)
|| actor->_f_Z() > target->_f_Z()+(target->GetDefault()->_f_height()) || actor->Z() > target->Z() + target->GetDefault()->Height
|| actor->_f_Top() < target->_f_Z()) || actor->Top() < target->Z())
{ {
newZ = target->_f_Z()+((pr_kspiritseek()*target->GetDefault()->_f_height())>>8); newZ = target->Z() + pr_kspiritseek() * target->GetDefault()->Height / 256;
deltaZ = newZ-actor->_f_Z(); deltaZ = newZ-actor->Z();
if (abs(deltaZ) > 15*FRACUNIT)
if (fabs(deltaZ) > 15)
{ {
if(deltaZ > 0) if(deltaZ > 0)
{ {
deltaZ = 15*FRACUNIT; deltaZ = 15;
} }
else else
{ {
deltaZ = -15*FRACUNIT; deltaZ = -15;
} }
} }
dist = actor->AproxDistance (target) / actor->_f_speed(); actor->Vel.Z = deltaZ + actor->DistanceBySpeed(target, actor->Speed);
if (dist < 1)
{
dist = 1;
}
actor->Vel.Z = FIXED2DBL(deltaZ/dist);
} }
return; return;
} }
@ -492,15 +478,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise)
// //
//============================================================================ //============================================================================
AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z, AActor *P_SpawnKoraxMissile (const DVector3 &pos, AActor *source, AActor *dest, PClassActor *type)
AActor *source, AActor *dest, PClassActor *type)
{ {
AActor *th; AActor *th;
DAngle an; DAngle an;
int dist; double dist;
z -= source->_f_floorclip(); th = Spawn (type, source->PosPlusZ(-source->Floorclip), ALLOW_REPLACE);
th = Spawn (type, x, y, z, ALLOW_REPLACE);
th->target = source; // Originator th->target = source; // Originator
an = th->AngleTo(dest); an = th->AngleTo(dest);
if (dest->flags & MF_SHADOW) if (dest->flags & MF_SHADOW)
@ -509,11 +493,7 @@ AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z,
} }
th->Angles.Yaw = an; th->Angles.Yaw = an;
th->VelFromAngle(); th->VelFromAngle();
dist = dest->AproxDistance (th) / th->_f_speed(); dist = dest->DistanceBySpeed(th, th->Speed);
if (dist < 1) th->Vel.Z = (dest->Z() - pos.Z + 30) / dist;
{
dist = 1;
}
th->Vel.Z = FIXED2DBL((dest->_f_Z()-z+(30*FRACUNIT))/dist);
return (P_CheckMissileSpawn(th, source->radius) ? th : NULL); return (P_CheckMissileSpawn(th, source->radius) ? th : NULL);
} }

View file

@ -128,8 +128,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
// every so many calls, spawn a new missile in its set directions // every so many calls, spawn a new missile in its set directions
if (spawndir & SHARDSPAWN_LEFT) if (spawndir & SHARDSPAWN_LEFT)
{ {
mo = P_SpawnMissileAngleZSpeed (self, self->_f_Z(), RUNTIME_CLASS(AFrostMissile), self->_f_angle()+(ANG45/9), mo = P_SpawnMissileAngleZSpeed(self, self->Z(), RUNTIME_CLASS(AFrostMissile),
0, (20+2*spermcount)<<FRACBITS, self->target); self->Angles.Yaw + 5, 0, (20. + 2 * spermcount), self->target);
if (mo) if (mo)
{ {
mo->special1 = SHARDSPAWN_LEFT; mo->special1 = SHARDSPAWN_LEFT;
@ -140,8 +140,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
} }
if (spawndir & SHARDSPAWN_RIGHT) if (spawndir & SHARDSPAWN_RIGHT)
{ {
mo = P_SpawnMissileAngleZSpeed (self, self->_f_Z(), RUNTIME_CLASS(AFrostMissile), self->_f_angle()-(ANG45/9), mo = P_SpawnMissileAngleZSpeed(self, self->Z(), RUNTIME_CLASS(AFrostMissile),
0, (20+2*spermcount)<<FRACBITS, self->target); self->Angles.Yaw - 5, 0, (20. + 2 * spermcount), self->target);
if (mo) if (mo)
{ {
mo->special1 = SHARDSPAWN_RIGHT; mo->special1 = SHARDSPAWN_RIGHT;
@ -152,8 +152,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
} }
if (spawndir & SHARDSPAWN_UP) if (spawndir & SHARDSPAWN_UP)
{ {
mo = P_SpawnMissileAngleZSpeed (self, self->_f_Z()+8*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->_f_angle(), mo = P_SpawnMissileAngleZSpeed(self, self->Z() + 8., RUNTIME_CLASS(AFrostMissile),
0, (15+2*spermcount)<<FRACBITS, self->target); self->Angles.Yaw, 0, (15. + 2 * spermcount), self->target);
if (mo) if (mo)
{ {
mo->Vel.Z = self->Vel.Z; mo->Vel.Z = self->Vel.Z;
@ -167,8 +167,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
} }
if (spawndir & SHARDSPAWN_DOWN) if (spawndir & SHARDSPAWN_DOWN)
{ {
mo = P_SpawnMissileAngleZSpeed (self, self->_f_Z()-4*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->_f_angle(), mo = P_SpawnMissileAngleZSpeed(self, self->Z() - 4., RUNTIME_CLASS(AFrostMissile),
0, (15+2*spermcount)<<FRACBITS, self->target); self->Angles.Yaw, 0, (15. + 2 * spermcount), self->target);
if (mo) if (mo)
{ {
mo->Vel.Z = self->Vel.Z; mo->Vel.Z = self->Vel.Z;

View file

@ -215,7 +215,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap)
PClassActor *lightning = PClass::FindActor(self->GetClass()->MissileName); PClassActor *lightning = PClass::FindActor(self->GetClass()->MissileName);
AActor *mo; AActor *mo;
fixed_t deltaZ;
if (lightning == NULL) if (lightning == NULL)
{ {
@ -230,32 +229,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap)
self->SetState (self->FindState(NAME_Death)); self->SetState (self->FindState(NAME_Death));
return 0; return 0;
} }
if (self->flags3 & MF3_FLOORHUGGER) double deltaX = (pr_zap() - 128) * self->radius / 256;
{ double deltaY = (pr_zap() - 128) * self->radius / 256;
deltaZ = 10*FRACUNIT; double deltaZ = (self->flags3 & MF3_FLOORHUGGER) ? 10 : -10;
}
else
{
deltaZ = -10*FRACUNIT;
}
fixed_t xo = ((pr_zap() - 128)*self->_f_radius() / 256);
fixed_t yo = ((pr_zap() - 128)*self->_f_radius() / 256);
mo = Spawn(lightning, self->Vec3Offset(xo, yo, deltaZ), ALLOW_REPLACE); mo = Spawn(lightning, self->Vec3Offset(deltaX, deltaY, deltaZ), ALLOW_REPLACE);
if (mo) if (mo)
{ {
mo->lastenemy = self; mo->lastenemy = self;
mo->Vel.X = self->Vel.X; mo->Vel.X = self->Vel.X;
mo->Vel.Y = self->Vel.Y; mo->Vel.Y = self->Vel.Y;
mo->Vel.Z = (self->flags3 & MF3_FLOORHUGGER) ? 20 : -20;
mo->target = self->target; mo->target = self->target;
if (self->flags3 & MF3_FLOORHUGGER)
{
mo->Vel.Z = 20;
}
else
{
mo->Vel.Z = -20;
}
} }
if ((self->flags3 & MF3_FLOORHUGGER) && pr_zapf() < 160) if ((self->flags3 & MF3_FLOORHUGGER) && pr_zapf() < 160)
{ {

View file

@ -193,7 +193,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffTrack)
{ {
self->tracer = P_RoughMonsterSearch (self, 10, true); self->tracer = P_RoughMonsterSearch (self, 10, true);
} }
P_SeekerMissile (self, ANGLE_1*2, ANGLE_1*10); P_SeekerMissile(self, 2, 10);
return 0; return 0;
} }
@ -229,12 +229,11 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *)
// //
//============================================================================ //============================================================================
void MStaffSpawn2 (AActor *actor, angle_t angle) void MStaffSpawn2 (AActor *actor, DAngle angle)
{ {
AActor *mo; AActor *mo;
mo = P_SpawnMissileAngleZ (actor, actor->_f_Z()+40*FRACUNIT, mo = P_SpawnMissileAngleZ (actor, actor->Z()+40, RUNTIME_CLASS(AMageStaffFX2), angle, 0.);
RUNTIME_CLASS(AMageStaffFX2), angle, 0);
if (mo) if (mo)
{ {
mo->target = actor; mo->target = actor;
@ -256,11 +255,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_MageAttack)
{ {
return 0; return 0;
} }
angle_t angle; DAngle angle = self->Angles.Yaw;
angle = self->_f_angle(); MStaffSpawn2(self, angle);
MStaffSpawn2 (self, angle); MStaffSpawn2(self, angle - 5);
MStaffSpawn2 (self, angle-ANGLE_1*5); MStaffSpawn2(self, angle + 5);
MStaffSpawn2 (self, angle+ANGLE_1*5); S_Sound(self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM);
S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM);
return 0; return 0;
} }

View file

@ -160,8 +160,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale)
FMultiBlockThingsIterator::CheckResult cres; FMultiBlockThingsIterator::CheckResult cres;
while (it.Next(&cres)) while (it.Next(&cres))
{ {
fixed_t blockdist = self->_f_radius() + cres.thing->_f_radius(); double blockdist = self->radius + cres.thing->radius;
if (abs(cres.thing->_f_X() - cres.position.x) >= blockdist || abs(cres.thing->_f_Y() - cres.position.y) >= blockdist) if (fabs(cres.thing->X() - cres.Position.X) >= blockdist || fabs(cres.thing->Y() - cres.Position.Y) >= blockdist)
continue; continue;
// Q: Make this z-aware for everything? It never was before. // Q: Make this z-aware for everything? It never was before.

View file

@ -53,13 +53,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon)
AMinotaurFriend *mo; AMinotaurFriend *mo;
mo = Spawn<AMinotaurFriend> (self->Pos(), ALLOW_REPLACE); mo = Spawn<AMinotaurFriend>(self->Pos(), ALLOW_REPLACE);
if (mo) if (mo)
{ {
if (P_TestMobjLocation(mo) == false || !self->tracer) if (P_TestMobjLocation(mo) == false || !self->tracer)
{ // Didn't fit - change back to artifact { // Didn't fit - change back to artifact
mo->Destroy (); mo->Destroy();
AActor *arti = Spawn<AArtiDarkServant> (self->_f_Pos(), ALLOW_REPLACE); AActor *arti = Spawn<AArtiDarkServant>(self->Pos(), ALLOW_REPLACE);
if (arti) arti->flags |= MF_DROPPED; if (arti) arti->flags |= MF_DROPPED;
return 0; return 0;
} }
@ -72,14 +72,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon)
else else
{ {
mo->tracer = self->tracer; // Pointer to master mo->tracer = self->tracer; // Pointer to master
AInventory *power = Spawn<APowerMinotaur> (0, 0, 0, NO_REPLACE); AInventory *power = Spawn<APowerMinotaur>();
power->CallTryPickup (self->tracer); power->CallTryPickup(self->tracer);
mo->SetFriendPlayer(self->tracer->player); mo->SetFriendPlayer(self->tracer->player);
} }
// Make smoke puff // Make smoke puff
Spawn ("MinotaurSmoke", self->Pos(), ALLOW_REPLACE); Spawn("MinotaurSmoke", self->Pos(), ALLOW_REPLACE);
S_Sound (self, CHAN_VOICE, mo->ActiveSound, 1, ATTN_NORM); S_Sound(self, CHAN_VOICE, mo->ActiveSound, 1, ATTN_NORM);
} }
return 0; return 0;
} }

View file

@ -15,12 +15,6 @@ static FRandom pr_wraithfx2 ("WraithFX2");
static FRandom pr_wraithfx3 ("WraithFX3"); static FRandom pr_wraithfx3 ("WraithFX3");
static FRandom pr_wraithfx4 ("WraithFX4"); static FRandom pr_wraithfx4 ("WraithFX4");
//============================================================================
// Wraith Variables
//
// special1 Internal index into floatbob
//============================================================================
//============================================================================ //============================================================================
// //
// A_WraithInit // A_WraithInit
@ -39,7 +33,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithInit)
self->SetZ(self->ceilingz - self->Height); self->SetZ(self->ceilingz - self->Height);
} }
self->special1 = 0; // index into floatbob self->WeaveIndexZ = 0; // index into floatbob
return 0; return 0;
} }
@ -156,15 +150,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX3)
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
AActor *mo; AActor *mo;
int numdropped = pr_wraithfx3()%15; int numdropped = pr_wraithfx3() % 15;
while (numdropped-- > 0) while (numdropped-- > 0)
{ {
fixed_t xo = (pr_wraithfx3() - 128) << 11; double xo = (pr_wraithfx3() - 128) / 32.;
fixed_t yo = (pr_wraithfx3() - 128) << 11; double yo = (pr_wraithfx3() - 128) / 32.;
fixed_t zo = pr_wraithfx3() << 10; double zo = pr_wraithfx3() / 64.;
mo = Spawn ("WraithFX3", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); mo = Spawn("WraithFX3", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo) if (mo)
{ {
mo->floorz = self->floorz; mo->floorz = self->floorz;
@ -212,9 +206,9 @@ void A_WraithFX4 (AActor *self)
if (spawn4) if (spawn4)
{ {
fixed_t xo = (pr_wraithfx4() - 128) << 12; double xo = (pr_wraithfx4() - 128) / 16.;
fixed_t yo = (pr_wraithfx4() - 128) << 12; double yo = (pr_wraithfx4() - 128) / 16.;
fixed_t zo = (pr_wraithfx4() << 10); double zo = (pr_wraithfx4() / 64.);
mo = Spawn ("WraithFX4", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); mo = Spawn ("WraithFX4", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo) if (mo)
@ -226,9 +220,9 @@ void A_WraithFX4 (AActor *self)
} }
if (spawn5) if (spawn5)
{ {
fixed_t xo = (pr_wraithfx4() - 128) << 11; double xo = (pr_wraithfx4() - 128) / 32.;
fixed_t yo = (pr_wraithfx4() - 128) << 11; double yo = (pr_wraithfx4() - 128) / 32.;
fixed_t zo = (pr_wraithfx4()<<10); double zo = (pr_wraithfx4() / 64.);
mo = Spawn ("WraithFX5", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); mo = Spawn ("WraithFX5", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo) if (mo)
@ -250,9 +244,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithChase)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
int weaveindex = self->special1; int weaveindex = self->WeaveIndexZ;
self->_f_AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8); self->AddZ(BobSin(weaveindex));
self->special1 = (weaveindex + 2) & 63; self->WeaveIndexZ = (weaveindex + 2) & 63;
// if (self->Floorclip > 0) // if (self->Floorclip > 0)
// { // {
// P_SetMobjState(self, S_WRAITH_RAISE2); // P_SetMobjState(self, S_WRAITH_RAISE2);

View file

@ -329,7 +329,7 @@ struct level_info_t
FString SoundInfo; FString SoundInfo;
FString SndSeq; FString SndSeq;
float teamdamage; double teamdamage;
FOptData optdata; FOptData optdata;
FMusicMap MusicMap; FMusicMap MusicMap;
@ -444,7 +444,7 @@ struct FLevelLocals
bool FromSnapshot; // The current map was restored from a snapshot bool FromSnapshot; // The current map was restored from a snapshot
float teamdamage; double teamdamage;
bool IsJumpingAllowed() const; bool IsJumpingAllowed() const;
bool IsCrouchingAllowed() const; bool IsCrouchingAllowed() const;

View file

@ -1150,7 +1150,7 @@ DEFINE_MAP_OPTION(teamdamage, true)
{ {
parse.ParseAssign(); parse.ParseAssign();
parse.sc.MustGetFloat(); parse.sc.MustGetFloat();
info->teamdamage = float(parse.sc.Float); info->teamdamage = parse.sc.Float;
} }
DEFINE_MAP_OPTION(mapbackground, true) DEFINE_MAP_OPTION(mapbackground, true)

View file

@ -1221,7 +1221,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
//Use the original damage to check for telefrag amount. Don't let the now-amplified damagetypes do it. //Use the original damage to check for telefrag amount. Don't let the now-amplified damagetypes do it.
if (rawdamage < TELEFRAG_DAMAGE || (target->flags7 & MF7_LAXTELEFRAGDMG)) if (rawdamage < TELEFRAG_DAMAGE || (target->flags7 & MF7_LAXTELEFRAGDMG))
{ // Still allow telefragging :-( { // Still allow telefragging :-(
damage = (int)((float)damage * level.teamdamage); damage = (int)(damage * level.teamdamage);
if (damage < 0) if (damage < 0)
{ {
return damage; return damage;
@ -1672,7 +1672,7 @@ bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poi
} }
if (source != NULL && source->player != player && player->mo->IsTeammate (source)) if (source != NULL && source->player != player && player->mo->IsTeammate (source))
{ {
poison = (int)((float)poison * level.teamdamage); poison = (int)(poison * level.teamdamage);
} }
if (poison > 0) if (poison > 0)
{ {

View file

@ -124,7 +124,7 @@ void P_PredictionLerpReset();
APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags=0); APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags=0);
int P_FaceMobj (AActor *source, AActor *target, DAngle *delta); int P_FaceMobj (AActor *source, AActor *target, DAngle *delta);
bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise = false, bool usecurspeed=false); bool P_SeekerMissile (AActor *actor, double thresh, double turnMax, bool precise = false, bool usecurspeed=false);
enum EPuffFlags enum EPuffFlags
{ {
@ -168,6 +168,10 @@ inline AActor *P_SpawnMissileXYZ(const fixedvec3 &pos, AActor *source, AActor *d
{ {
return P_SpawnMissileXYZ(pos.x, pos.y, pos.z, source, dest, type, checkspawn, owner); return P_SpawnMissileXYZ(pos.x, pos.y, pos.z, source, dest, type, checkspawn, owner);
} }
inline AActor *P_SpawnMissileXYZ(const DVector3 &pos, AActor *source, AActor *dest, PClassActor *type, bool checkspawn = true, AActor *owner = NULL)
{
return P_SpawnMissileXYZ(FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), source, dest, type, checkspawn, owner);
}
AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, angle_t angle, fixed_t vz); AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, angle_t angle, fixed_t vz);
inline AActor *P_SpawnMissileAngle(AActor *source, PClassActor *type, DAngle angle, double vz) inline AActor *P_SpawnMissileAngle(AActor *source, PClassActor *type, DAngle angle, double vz)
{ {
@ -180,6 +184,10 @@ inline AActor *P_SpawnMissileAngleZ(AActor *source, double z, PClassActor *type,
return P_SpawnMissileAngleZ(source, FLOAT2FIXED(z), type, angle.BAMs(), FLOAT2FIXED(vz)); return P_SpawnMissileAngleZ(source, FLOAT2FIXED(z), type, angle.BAMs(), FLOAT2FIXED(vz));
} }
AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, PClassActor *type, angle_t angle, fixed_t vz, fixed_t speed, AActor *owner=NULL, bool checkspawn = true); AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, PClassActor *type, angle_t angle, fixed_t vz, fixed_t speed, AActor *owner=NULL, bool checkspawn = true);
inline AActor *P_SpawnMissileAngleZSpeed(AActor *source, double z, PClassActor *type, DAngle angle, double vz, double speed, AActor *owner = NULL, bool checkspawn = true)
{
return P_SpawnMissileAngleZSpeed(source, FLOAT2FIXED(z), type, angle.BAMs(), FLOAT2FIXED(vz), FLOAT2FIXED(speed), owner, checkspawn);
}
AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassActor *type); AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassActor *type);
AActor *P_SpawnPlayerMissile (AActor* source, PClassActor *type); AActor *P_SpawnPlayerMissile (AActor* source, PClassActor *type);

View file

@ -1106,6 +1106,9 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite
item->thing = thing; item->thing = thing;
item->position = checkpoint + Displacements.getOffset(basegroup, thing->Sector->PortalGroup); item->position = checkpoint + Displacements.getOffset(basegroup, thing->Sector->PortalGroup);
item->portalflags = portalflags; item->portalflags = portalflags;
// same as above in floating point. This is here so that this stuff can be converted piece by piece.
item->Position = { FIXED2DBL(item->position.x), FIXED2DBL(item->position.y), FIXED2DBL(item->position.z) };
return true; return true;
} }
bool onlast = unsigned(index + 1) >= checklist.Size(); bool onlast = unsigned(index + 1) >= checklist.Size();

View file

@ -15,6 +15,14 @@ struct divline_t
fixed_t dy; fixed_t dy;
}; };
struct fdivline_t
{
fixed_t x;
fixed_t y;
fixed_t dx;
fixed_t dy;
};
struct intercept_t struct intercept_t
{ {
fixed_t frac; // along trace line fixed_t frac; // along trace line
@ -336,7 +344,8 @@ public:
struct CheckResult struct CheckResult
{ {
AActor *thing; AActor *thing;
fixedvec3 position; fixedvec3 position; // keep these both until the fixed version can be removed.
DVector3 Position;
int portalflags; int portalflags;
}; };

View file

@ -1681,11 +1681,8 @@ bool AActor::CanSeek(AActor *target) const
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool P_SeekerMissile (AActor *actor, angle_t _thresh, angle_t _turnMax, bool precise, bool usecurspeed) bool P_SeekerMissile (AActor *actor, double thresh, double turnMax, bool precise, bool usecurspeed)
{ {
DAngle thresh = ANGLE2DBL(_thresh);
DAngle turnMax = ANGLE2DBL(_turnMax);
int dir; int dir;
DAngle delta; DAngle delta;
AActor *target; AActor *target;
@ -3086,7 +3083,7 @@ bool AActor::AdjustReflectionAngle (AActor *thing, DAngle &angle)
if (thing->flags4&MF4_SHIELDREFLECT) if (thing->flags4&MF4_SHIELDREFLECT)
{ {
// Shield reflection (from the Centaur) // Shield reflection (from the Centaur)
if (diffangle(angle, thing->Angles.Yaw) > 45) if (absangle(angle, thing->Angles.Yaw) > 45)
return true; // Let missile explode return true; // Let missile explode
if (thing->IsKindOf (RUNTIME_CLASS(AHolySpirit))) // shouldn't this be handled by another flag??? if (thing->IsKindOf (RUNTIME_CLASS(AHolySpirit))) // shouldn't this be handled by another flag???

View file

@ -929,6 +929,10 @@ inline void P_SpawnTeleportFog(AActor *mobj, const DVector3 &pos, bool beforeTel
P_SpawnTeleportFog(mobj, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), beforeTele, setTarget); P_SpawnTeleportFog(mobj, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), beforeTele, setTarget);
} }
bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, DAngle angle, int flags); // bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, DAngle angle, int flags); // bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false
inline bool P_Teleport(AActor *thing, const DVector3 &pos, DAngle angle, int flags)
{
return P_Teleport(thing, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), angle, flags);
}
bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags); bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags);
bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse); bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse);
bool EV_TeleportOther (int other_tid, int dest_tid, bool fog); bool EV_TeleportOther (int other_tid, int dest_tid, bool fog);

View file

@ -803,7 +803,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SeekerMissile)
{ {
self->tracer = P_RoughMonsterSearch (self, distance, true); self->tracer = P_RoughMonsterSearch (self, distance, true);
} }
if (!P_SeekerMissile(self, clamp<int>(ang1, 0, 90) * ANGLE_1, clamp<int>(ang2, 0, 90) * ANGLE_1, !!(flags & SMF_PRECISE), !!(flags & SMF_CURSPEED))) if (!P_SeekerMissile(self, clamp<int>(ang1, 0, 90), clamp<int>(ang2, 0, 90), !!(flags & SMF_PRECISE), !!(flags & SMF_CURSPEED)))
{ {
if (flags & SMF_LOOK) if (flags & SMF_LOOK)
{ // This monster is no longer seekable, so let us look for another one next time. { // This monster is no longer seekable, so let us look for another one next time.

View file

@ -1107,13 +1107,13 @@ inline TAngle<T> deltaangle(double a1, const TAngle<T> &a2)
} }
template<class T> template<class T>
inline TAngle<T> diffangle(const TAngle<T> &a1, const TAngle<T> &a2) inline TAngle<T> absangle(const TAngle<T> &a1, const TAngle<T> &a2)
{ {
return fabs((a1 - a2).Normalize180()); return fabs((a1 - a2).Normalize180());
} }
template<class T> template<class T>
inline TAngle<T> diffangle(const TAngle<T> &a1, double a2) inline TAngle<T> absangle(const TAngle<T> &a1, double a2)
{ {
return fabs((a1 - a2).Normalize180()); return fabs((a1 - a2).Normalize180());
} }