diff --git a/src/p_acs.cpp b/src/p_acs.cpp index f21a5b91a..1f28ed636 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5990,7 +5990,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) if (activator == NULL || !reference) return false; - if (P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags, heightoffset, radiusoffset, pitch)) + if (P_Thing_Warp(activator, reference, ACSToDouble(xofs), ACSToDouble(yofs), ACSToDouble(zofs), ACSToAngle(angle), flags, ACSToDouble(heightoffset), ACSToDouble(radiusoffset), ACSToAngle(pitch))) { if (state && argCount > 6) { diff --git a/src/p_effect.cpp b/src/p_effect.cpp index 442d5fd4c..ba994d4e2 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -313,7 +313,7 @@ void P_ThinkParticles () } } -void P_SpawnParticle(fixed_t x, fixed_t y, fixed_t z, fixed_t vx, fixed_t vy, fixed_t vz, PalEntry color, bool fullbright, BYTE startalpha, BYTE lifetime, WORD size, int fadestep, fixed_t accelx, fixed_t accely, fixed_t accelz) +void P_SpawnParticle(fixed_t x, fixed_t y, fixed_t z, fixed_t vx, fixed_t vy, fixed_t vz, PalEntry color, bool fullbright, BYTE startalpha, BYTE lifetime, int size, int fadestep, fixed_t accelx, fixed_t accely, fixed_t accelz) { particle_t *particle = NewParticle(); @@ -334,7 +334,7 @@ void P_SpawnParticle(fixed_t x, fixed_t y, fixed_t z, fixed_t vx, fixed_t vy, fi particle->accy = accely; particle->accz = accelz; particle->bright = fullbright; - particle->size = size; + particle->size = (WORD)size; } } diff --git a/src/p_effect.h b/src/p_effect.h index 4d246af83..856f0d824 100644 --- a/src/p_effect.h +++ b/src/p_effect.h @@ -83,7 +83,12 @@ particle_t *JitterParticle (int ttl); particle_t *JitterParticle (int ttl, double drift); void P_ThinkParticles (void); -void P_SpawnParticle(fixed_t x, fixed_t y, fixed_t z, fixed_t vx, fixed_t vy, fixed_t vz, PalEntry color, bool fullbright, BYTE startalpha, BYTE lifetime, WORD size, int fadestep, fixed_t accelx, fixed_t accely, fixed_t accelz); +void P_SpawnParticle(fixed_t x, fixed_t y, fixed_t z, fixed_t vx, fixed_t vy, fixed_t vz, PalEntry color, bool fullbright, BYTE startalpha, BYTE lifetime, int size, int fadestep, fixed_t accelx, fixed_t accely, fixed_t accelz); +inline void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, bool fullbright, double startalpha, int lifetime, WORD size, double fadestep) +{ + P_SpawnParticle(FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), FLOAT2FIXED(vel.X), FLOAT2FIXED(vel.Y), FLOAT2FIXED(vel.Z), + color, fullbright, BYTE(startalpha * 255), BYTE(lifetime), WORD(size), fadestep < 0 ? -1 : int(fadestep * 255), FLOAT2FIXED(accel.X), FLOAT2FIXED(accel.Y), FLOAT2FIXED(accel.Z)); +} void P_InitEffects (void); void P_RunEffects (void); diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index aadc8a718..41cf7af23 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1165,23 +1165,23 @@ void P_RandomChaseDir (AActor *actor) bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams *params) { - fixed_t maxdist; - fixed_t mindist; - angle_t fov; + double maxdist; + double mindist; + DAngle fov; if (params != NULL) { - maxdist = params->maxdist; - mindist = params->mindist; - fov = params->fov; + maxdist = params->maxDist; + mindist = params->minDist; + fov = params->Fov; } else { mindist = maxdist = 0; - fov = allaround ? 0 : ANGLE_180; + fov = allaround ? 0. : 180.; } - fixed_t dist = lookee->AproxDistance (other); + double dist = lookee->Distance2D (other); if (maxdist && dist > maxdist) return false; // [KS] too far @@ -1189,15 +1189,15 @@ bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams if (mindist && dist < mindist) return false; // [KS] too close - if (fov && fov < ANGLE_MAX) + if (fov != 0) { - angle_t an = lookee->__f_AngleTo(other) - lookee->_f_angle(); + DAngle an = absangle(lookee->AngleTo(other), lookee->Angles.Yaw); - if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) + if (an > (fov / 2)) { // if real close, react anyway // [KS] but respect minimum distance rules - if (mindist || dist > FLOAT2FIXED(lookee->meleerange + lookee->radius)) + if (mindist || dist > lookee->meleerange + lookee->radius) return false; // outside of fov } } @@ -1887,15 +1887,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx) { PARAM_ACTION_PROLOGUE; PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (minseedist) { minseedist = 0; } - PARAM_FIXED_OPT (maxseedist) { maxseedist = 0; } - PARAM_FIXED_OPT (maxheardist) { maxheardist = 0; } - PARAM_FLOAT_OPT (fov_f) { fov_f = 0; } + PARAM_FLOAT_OPT (minseedist) { minseedist = 0; } + PARAM_FLOAT_OPT (maxseedist) { maxseedist = 0; } + PARAM_FLOAT_OPT (maxheardist) { maxheardist = 0; } + PARAM_DANGLE_OPT (fov) { fov = 0.; } PARAM_STATE_OPT (seestate) { seestate = NULL; } AActor *targ = NULL; // Shuts up gcc fixed_t dist; - angle_t fov = (fov_f == 0) ? ANGLE_180 : FLOAT2ANGLE(fov_f); + if (fov == 0) fov = 180.; FLookExParams params = { fov, minseedist, maxseedist, maxheardist, flags, seestate }; if (self->flags5 & MF5_INCONVERSATION) @@ -2817,7 +2817,7 @@ enum FAF_Flags FAF_TOP = 4, FAF_NODISTFACTOR = 8, // deprecated }; -void A_Face (AActor *self, AActor *other, angle_t _max_turn, angle_t _max_pitch, angle_t _ang_offset, angle_t _pitch_offset, int flags, fixed_t z_add) +void A_Face(AActor *self, AActor *other, DAngle max_turn, DAngle max_pitch, DAngle ang_offset, DAngle pitch_offset, int flags, double z_add) { if (!other) return; @@ -2830,12 +2830,7 @@ void A_Face (AActor *self, AActor *other, angle_t _max_turn, angle_t _max_pitch, self->flags &= ~MF_AMBUSH; - DAngle max_turn = ANGLE2DBL(_max_turn); - DAngle ang_offset = ANGLE2DBL(_ang_offset); - DAngle max_pitch = ANGLE2DBL(_max_pitch); - DAngle pitch_offset = ANGLE2DBL(_pitch_offset); DAngle other_angle = self->AngleTo(other); - DAngle delta = deltaangle(self->Angles.Yaw, other_angle); // 0 means no limit. Also, if we turn in a single step anyways, no need to go through the algorithms. @@ -2882,7 +2877,7 @@ void A_Face (AActor *self, AActor *other, angle_t _max_turn, angle_t _max_pitch, if (flags & FAF_TOP) target_z = other->Top() + other->GetBobOffset(); - target_z += FIXED2FLOAT(z_add); + target_z += z_add; double dist_z = target_z - source_z; double ddist = g_sqrt(dist.X*dist.X + dist.Y*dist.Y + dist_z*dist_z); @@ -2926,12 +2921,12 @@ void A_FaceTarget(AActor *self) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTarget) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(max_turn) { max_turn = 0; } - PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270; } - PARAM_ANGLE_OPT(ang_offset) { ang_offset = 0; } - PARAM_ANGLE_OPT(pitch_offset) { pitch_offset = 0; } + PARAM_DANGLE_OPT(max_turn) { max_turn = 0.; } + PARAM_DANGLE_OPT(max_pitch) { max_pitch = 270.; } + PARAM_DANGLE_OPT(ang_offset) { ang_offset = 0.; } + PARAM_DANGLE_OPT(pitch_offset) { pitch_offset = 0.; } PARAM_INT_OPT(flags) { flags = 0; } - PARAM_FIXED_OPT(z_add) { z_add = 0; } + PARAM_FLOAT_OPT(z_add) { z_add = 0; } A_Face(self, self->target, max_turn, max_pitch, ang_offset, pitch_offset, flags, z_add); return 0; @@ -2940,12 +2935,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTarget) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMaster) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(max_turn) { max_turn = 0; } - PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270; } - PARAM_ANGLE_OPT(ang_offset) { ang_offset = 0; } - PARAM_ANGLE_OPT(pitch_offset) { pitch_offset = 0; } - PARAM_INT_OPT(flags) { flags = 0; } - PARAM_FIXED_OPT(z_add) { z_add = 0; } + PARAM_DANGLE_OPT(max_turn) { max_turn = 0.; } + PARAM_DANGLE_OPT(max_pitch) { max_pitch = 270.; } + PARAM_DANGLE_OPT(ang_offset) { ang_offset = 0.; } + PARAM_DANGLE_OPT(pitch_offset) { pitch_offset = 0.; } + PARAM_INT_OPT(flags) { flags = 0; } + PARAM_FLOAT_OPT(z_add) { z_add = 0; } A_Face(self, self->master, max_turn, max_pitch, ang_offset, pitch_offset, flags, z_add); return 0; @@ -2954,12 +2949,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMaster) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTracer) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(max_turn) { max_turn = 0; } - PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270; } - PARAM_ANGLE_OPT(ang_offset) { ang_offset = 0; } - PARAM_ANGLE_OPT(pitch_offset) { pitch_offset = 0; } - PARAM_INT_OPT(flags) { flags = 0; } - PARAM_FIXED_OPT(z_add) { z_add = 0; } + PARAM_DANGLE_OPT(max_turn) { max_turn = 0.; } + PARAM_DANGLE_OPT(max_pitch) { max_pitch = 270.; } + PARAM_DANGLE_OPT(ang_offset) { ang_offset = 0.; } + PARAM_DANGLE_OPT(pitch_offset) { pitch_offset = 0.; } + PARAM_INT_OPT(flags) { flags = 0; } + PARAM_FLOAT_OPT(z_add) { z_add = 0; } A_Face(self, self->tracer, max_turn, max_pitch, ang_offset, pitch_offset, flags, z_add); return 0; diff --git a/src/p_enemy.h b/src/p_enemy.h index 467e74eba..2912f847f 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -38,10 +38,10 @@ enum LO_Flags struct FLookExParams { - angle_t fov; - fixed_t mindist; - fixed_t maxdist; - fixed_t maxheardist; + DAngle Fov; + double minDist; + double maxDist; + double maxHeardist; int flags; FState *seestate; }; @@ -78,7 +78,7 @@ void A_BossDeath(AActor *self); void A_Wander(AActor *self, int flags = 0); void A_Chase(VMFrameStack *stack, AActor *self); void A_FaceTarget(AActor *actor); -void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0, fixed_t z_add = 0); +void A_Face(AActor *self, AActor *other, DAngle max_turn = 0., DAngle max_pitch = 270., DAngle ang_offset = 0., DAngle pitch_offset = 0., int flags = 0, double z_add = 0); bool A_RaiseMobj (AActor *, double speed); bool A_SinkMobj (AActor *, double speed); diff --git a/src/p_local.h b/src/p_local.h index f0f4a5aea..367f54b3a 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -221,7 +221,7 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser); bool P_Thing_CanRaise(AActor *thing); PClassActor *P_GetSpawnableType(int spawnnum); void InitSpawnablesFromMapinfo(); -int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset, fixed_t radiusoffset, angle_t pitch); +int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, double zofs, DAngle angle, int flags, double heightoffset, double radiusoffset, DAngle pitch); enum WARPF { @@ -302,6 +302,10 @@ inline bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const sec return P_TryMove(thing, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), dropoff, onfloor, tm, missileCheck); } bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y); +inline bool P_CheckMove(AActor *thing, double x, double y) +{ + return P_CheckMove(thing, FLOAT2FIXED(x), FLOAT2FIXED(y)); +} void P_ApplyTorque(AActor *mo); bool P_TeleportMove (AActor* thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag, bool modifyactor = true); // [RH] Added z and telefrag parameters inline bool P_TeleportMove(AActor* thing, const fixedvec3 &pos, bool telefrag, bool modifyactor = true) diff --git a/src/p_maputl.h b/src/p_maputl.h index 6556029cd..96053dc90 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -356,6 +356,10 @@ public: FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1, bool ignorerestricted = false); FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted, sector_t *newsec); + FMultiBlockThingsIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted, sector_t *newsec) + : FMultiBlockThingsIterator(check, FLOAT2FIXED(checkx), FLOAT2FIXED(checky), FLOAT2FIXED(checkz), FLOAT2FIXED(checkh), FLOAT2FIXED(checkradius), ignorerestricted, newsec) + { + } bool Next(CheckResult *item); void Reset(); const FBoundingBox &Box() const diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index ed578dd8e..ed4c97409 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -419,7 +419,7 @@ void P_BobWeapon (player_t *player, pspdef_t *psp, float *x, float *y) { float bobx = float(player->bob * Rangex); float boby = float(player->bob * Rangey); - switch (level.levelnum)//bobstyle) + switch (bobstyle) { case AWeapon::BobNormal: *x = bobx * angle.Cos(); diff --git a/src/p_things.cpp b/src/p_things.cpp index 1866c079e..1fa0905b1 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -670,7 +670,7 @@ void InitSpawnablesFromMapinfo() } -int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset, fixed_t radiusoffset, angle_t pitch) +int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, double zofs, DAngle angle, int flags, double heightoffset, double radiusoffset, DAngle pitch) { if (flags & WARPF_MOVEPTR) { @@ -679,32 +679,33 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, caller = temp; } - fixedvec3 old = caller->_f_Pos(); + DVector3 old = caller->Pos(); int oldpgroup = caller->Sector->PortalGroup; - zofs += FixedMul(reference->_f_height(), heightoffset); + zofs += reference->Height * heightoffset; if (!(flags & WARPF_ABSOLUTEANGLE)) { - angle += (flags & WARPF_USECALLERANGLE) ? caller->_f_angle() : reference->_f_angle(); + angle += (flags & WARPF_USECALLERANGLE) ? caller->Angles.Yaw: reference->Angles.Yaw; } - const fixed_t rad = FixedMul(radiusoffset, reference->_f_radius()); - const angle_t fineangle = angle >> ANGLETOFINESHIFT; + const double rad = radiusoffset * reference->radius; + const double s = angle.Sin(); + const double c = angle.Cos(); if (!(flags & WARPF_ABSOLUTEPOSITION)) { if (!(flags & WARPF_ABSOLUTEOFFSET)) { - fixed_t xofs1 = xofs; + double xofs1 = xofs; // (borrowed from A_SpawnItemEx, assumed workable) // in relative mode negative y values mean 'left' and positive ones mean 'right' // This is the inverse orientation of the absolute mode! - xofs = FixedMul(xofs1, finecosine[fineangle]) + FixedMul(yofs, finesine[fineangle]); - yofs = FixedMul(xofs1, finesine[fineangle]) - FixedMul(yofs, finecosine[fineangle]); + xofs = xofs1 * c + yofs * s; + yofs = xofs1 * s - yofs * c; } if (flags & WARPF_TOFLOOR) @@ -713,30 +714,21 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, // now the caller's floorz should be appropriate for the assigned xy-position // assigning position again with. // extra unlink, link and environment calculation - caller->SetOrigin(reference->Vec3Offset( - xofs + FixedMul(rad, finecosine[fineangle]), - yofs + FixedMul(rad, finesine[fineangle]), - 0), true); - caller->_f_SetZ(caller->_f_floorz() + zofs); + caller->SetOrigin(reference->Vec3Offset(xofs + rad * c, yofs + rad * s, 0.), true); + // The two-step process is important. + caller->SetZ(caller->floorz + zofs); } else { - caller->SetOrigin(reference->Vec3Offset( - xofs + FixedMul(rad, finecosine[fineangle]), - yofs + FixedMul(rad, finesine[fineangle]), - zofs), true); + caller->SetOrigin(reference->Vec3Offset(xofs + rad * c, yofs + rad * s, zofs), true); } } else // [MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's. { + caller->SetOrigin(xofs + rad * c, yofs + rad * s, zofs, true); if (flags & WARPF_TOFLOOR) { - caller->SetOrigin(xofs + FixedMul(rad, finecosine[fineangle]), yofs + FixedMul(rad, finesine[fineangle]), zofs, true); - caller->_f_SetZ(caller->_f_floorz() + zofs); - } - else - { - caller->SetOrigin(xofs + FixedMul(rad, finecosine[fineangle]), yofs + FixedMul(rad, finesine[fineangle]), zofs, true); + caller->SetZ(caller->floorz + zofs); } } @@ -748,13 +740,13 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, } else { - caller->Angles.Yaw = ANGLE2DBL(angle); + caller->Angles.Yaw = angle; if (flags & WARPF_COPYPITCH) caller->SetPitch(reference->Angles.Pitch, false); - if (pitch) - caller->SetPitch(caller->Angles.Pitch + ANGLE2DBL(pitch), false); + if (pitch != 0) + caller->SetPitch(caller->Angles.Pitch + pitch, false); if (flags & WARPF_COPYVELOCITY) { @@ -765,6 +757,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, caller->Vel.Zero(); } +#if 0 // needs fixing // this is no fun with line portals if (flags & WARPF_WARPINTERPOLATION) { @@ -789,9 +782,11 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, { caller->ClearInterpolation(); } +#endif + if ((flags & WARPF_BOB) && (reference->flags2 & MF2_FLOATBOB)) { - caller->_f_AddZ(reference->_f_GetBobOffset()); + caller->AddZ(reference->GetBobOffset()); } } return true; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 43114b985..89857ae1b 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1893,7 +1893,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) PARAM_FLOAT_OPT (spawnofs_z) { spawnofs_z = 0; } PARAM_INT_OPT (SpiralOffset) { SpiralOffset = 270; } - if (range == 0) range = 8192*FRACUNIT; + if (range == 0) range = 8192.; if (sparsity == 0) sparsity = 1; FTranslatedLineTarget t; @@ -2254,7 +2254,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) } if (flags & SIXF_TELEFRAG) { - P_TeleportMove(mo, mo->_f_Pos(), true); + P_TeleportMove(mo, mo->Pos(), true); // This is needed to ensure consistent behavior. // Otherwise it will only spawn if nothing gets telefragged flags |= SIXF_NOCHECKPOSITION; @@ -2393,7 +2393,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem) { PARAM_ACTION_PROLOGUE; PARAM_CLASS_OPT (missile, AActor) { missile = PClass::FindActor("Unknown"); } - PARAM_FIXED_OPT (distance) { distance = 0; } + PARAM_FLOAT_OPT (distance) { distance = 0; } PARAM_FLOAT_OPT (zheight) { zheight = 0; } PARAM_BOOL_OPT (useammo) { useammo = true; } PARAM_BOOL_OPT (transfer_translation) { transfer_translation = false; } @@ -2412,7 +2412,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem) if (distance == 0) { // use the minimum distance that does not result in an overlap - distance = (self->_f_radius() + GetDefaultByType(missile)->_f_radius()) >> FRACBITS; + distance = (self->radius + GetDefaultByType(missile)->radius); } if (ACTION_CALL_FROM_WEAPON()) @@ -2531,9 +2531,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (missile, AActor); - PARAM_FIXED_OPT (zheight) { zheight = 0; } + PARAM_FLOAT_OPT (zheight) { zheight = 0; } PARAM_FLOAT_OPT (xyvel) { xyvel = 0; } - PARAM_FIXED_OPT (zvel) { zvel = 0; } + PARAM_FLOAT_OPT (zvel) { zvel = 0; } PARAM_BOOL_OPT (useammo) { useammo = true; } if (missile == NULL) @@ -2995,51 +2995,51 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnParticle) PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (lifetime) { lifetime = 35; } PARAM_INT_OPT (size) { size = 1; } - PARAM_ANGLE_OPT (angle) { angle = 0; } - PARAM_FIXED_OPT (xoff) { xoff = 0; } - PARAM_FIXED_OPT (yoff) { yoff = 0; } - PARAM_FIXED_OPT (zoff) { zoff = 0; } - PARAM_FIXED_OPT (xvel) { xvel = 0; } - PARAM_FIXED_OPT (yvel) { yvel = 0; } - PARAM_FIXED_OPT (zvel) { zvel = 0; } - PARAM_FIXED_OPT (accelx) { accelx = 0; } - PARAM_FIXED_OPT (accely) { accely = 0; } - PARAM_FIXED_OPT (accelz) { accelz = 0; } - PARAM_FIXED_OPT (startalphaf) { startalphaf = FRACUNIT; } - PARAM_FIXED_OPT (fadestepf) { fadestepf = -FRACUNIT; } + PARAM_DANGLE_OPT(angle) { angle = 0.; } + PARAM_FLOAT_OPT (xoff) { xoff = 0; } + PARAM_FLOAT_OPT (yoff) { yoff = 0; } + PARAM_FLOAT_OPT (zoff) { zoff = 0; } + PARAM_FLOAT_OPT (xvel) { xvel = 0; } + PARAM_FLOAT_OPT (yvel) { yvel = 0; } + PARAM_FLOAT_OPT (zvel) { zvel = 0; } + PARAM_FLOAT_OPT (accelx) { accelx = 0; } + PARAM_FLOAT_OPT (accely) { accely = 0; } + PARAM_FLOAT_OPT (accelz) { accelz = 0; } + PARAM_FLOAT_OPT (startalpha) { startalpha = 1.; } + PARAM_FLOAT_OPT (fadestep) { fadestep = -1.; } - BYTE startalpha = (BYTE)(clamp(startalphaf, 0, FRACUNIT) * 255 / FRACUNIT); - int fadestep = fadestepf < 0 ? -1 : clamp(fadestepf, 0, FRACUNIT) * 255 / FRACUNIT; - lifetime = clamp(lifetime, 0, 255); // Clamp to byte + startalpha = clamp(startalpha, 0., 1.); + if (fadestep > 0) fadestep = clamp(fadestep, 0., 1.); size = clamp(size, 0, 65535); // Clamp to word if (lifetime != 0) { - const angle_t ang = (angle + ((flags & SPF_RELANG) ? self->_f_angle() : 0)) >> ANGLETOFINESHIFT; - fixedvec3 pos; + if (flags & SPF_RELANG) angle += self->Angles.Yaw; + double s = angle.Sin(); + double c = angle.Cos(); + DVector3 pos(xoff, yoff, zoff); + DVector3 vel(xvel, yvel, zvel); + DVector3 acc(accelx, accely, accelz); //[MC] Code ripped right out of A_SpawnItemEx. if (flags & SPF_RELPOS) { // in relative mode negative y values mean 'left' and positive ones mean 'right' // This is the inverse orientation of the absolute mode! - const fixed_t xof1 = xoff; - xoff = FixedMul(xof1, finecosine[ang]) + FixedMul(yoff, finesine[ang]); - yoff = FixedMul(xof1, finesine[ang]) - FixedMul(yoff, finecosine[ang]); + pos.X = xoff * c + yoff * s; + pos.Y = xoff * s - yoff * c; } if (flags & SPF_RELVEL) { - const fixed_t newxvel = FixedMul(xvel, finecosine[ang]) + FixedMul(yvel, finesine[ang]); - yvel = FixedMul(xvel, finesine[ang]) - FixedMul(yvel, finecosine[ang]); - xvel = newxvel; + vel.X = xvel * c + yvel * s; + vel.Y = xvel * s - yvel * c; } if (flags & SPF_RELACCEL) { - fixed_t newaccelx = FixedMul(accelx, finecosine[ang]) + FixedMul(accely, finesine[ang]); - accely = FixedMul(accelx, finesine[ang]) - FixedMul(accely, finecosine[ang]); - accelx = newaccelx; + acc.X = accelx * c + accely * s; + acc.Y = accelx * s - accely * c; } pos = self->Vec3Offset(xoff, yoff, zoff); - P_SpawnParticle(pos.x, pos.y, pos.z, xvel, yvel, zvel, color, !!(flags & SPF_FULLBRIGHT), startalpha, lifetime, size, fadestep, accelx, accely, accelz); + P_SpawnParticle(self->Vec3Offset(pos), vel, acc, color, !!(flags & SPF_FULLBRIGHT), startalpha, lifetime, size, fadestep); } return 0; } @@ -3082,36 +3082,37 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight) // Useful for maps with many multi-actor special effects. // //=========================================================================== -static bool DoCheckSightOrRange(AActor *self, AActor *camera, double range, bool twodi) +static bool DoCheckSightOrRange(AActor *self, AActor *camera, double range, bool twodi, bool checksight) { if (camera == NULL) { return false; } // Check distance first, since it's cheaper than checking sight. - fixedvec2 pos = camera->_f_Vec2To(self); - fixed_t dz; - fixed_t eyez = (camera->_f_Top() - (camera->_f_height()>>2)); // same eye height as P_CheckSight - if (eyez > self->_f_Top()) + DVector2 pos = camera->Vec2To(self); + double dz; + double eyez = camera->Center(); + if (eyez > self->Top()) { - dz = self->_f_Top() - eyez; + dz = self->Top() - eyez; } - else if (eyez < self->_f_Z()) + else if (eyez < self->Z()) { - dz = self->_f_Z() - eyez; + dz = self->Z() - eyez; } else { dz = 0; } - double distance = ((double)pos.x * pos.x) + ((double)pos.y * pos.y) + (twodi == 0? ((double)dz * dz) : 0); - if (distance <= range){ + double distance = DVector3(pos, twodi? 0. : dz).LengthSquared(); + if (distance <= range*range) + { // Within range return true; } // Now check LOS. - if (P_CheckSight(camera, self, SF_IGNOREVISIBILITY)) + if (checksight && P_CheckSight(camera, self, SF_IGNOREVISIBILITY)) { // Visible return true; } @@ -3125,19 +3126,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange) PARAM_STATE(jump); PARAM_BOOL_OPT(twodi) { twodi = false; } - range = range * range * (double(FRACUNIT) * FRACUNIT); // no need for square roots + range *= range; for (int i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i]) { // Always check from each player. - if (DoCheckSightOrRange(self, players[i].mo, range, twodi)) + if (DoCheckSightOrRange(self, players[i].mo, range, twodi, true)) { ACTION_RETURN_STATE(NULL); } // If a player is viewing from a non-player, check that too. if (players[i].camera != NULL && players[i].camera->player == NULL && - DoCheckSightOrRange(self, players[i].camera, range, twodi)) + DoCheckSightOrRange(self, players[i].camera, range, twodi, true)) { ACTION_RETURN_STATE(NULL); } @@ -3146,42 +3147,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange) ACTION_RETURN_STATE(jump); } -//=========================================================================== -// -// A_CheckRange -// Jumps if this actor is out of range of all players. -// -//=========================================================================== -static bool DoCheckRange(AActor *self, AActor *camera, double range, bool twodi) -{ - if (camera == NULL) - { - return false; - } - // Check distance first, since it's cheaper than checking sight. - fixedvec2 pos = camera->_f_Vec2To(self); - fixed_t dz; - fixed_t eyez = (camera->_f_Top() - (camera->_f_height()>>2)); // same eye height as P_CheckSight - if (eyez > self->_f_Top()) - { - dz = self->_f_Top() - eyez; - } - else if (eyez < self->_f_Z()) - { - dz = self->_f_Z() - eyez; - } - else - { - dz = 0; - } - double distance = ((double)pos.x * pos.x) + ((double)pos.y * pos.y) + (twodi == 0? ((double)dz * dz) : 0); - - if (distance <= range){ - // Within range - return true; - } - return false; -} DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckRange) { @@ -3190,19 +3155,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckRange) PARAM_STATE(jump); PARAM_BOOL_OPT(twodi) { twodi = false; } - range = range * range * (double(FRACUNIT) * FRACUNIT); // no need for square roots + range *= range; for (int i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i]) { // Always check from each player. - if (DoCheckRange(self, players[i].mo, range, twodi)) + if (DoCheckSightOrRange(self, players[i].mo, range, twodi, false)) { ACTION_RETURN_STATE(NULL); } // If a player is viewing from a non-player, check that too. if (players[i].camera != NULL && players[i].camera->player == NULL && - DoCheckRange(self, players[i].camera, range, twodi)) + DoCheckSightOrRange(self, players[i].camera, range, twodi, false)) { ACTION_RETURN_STATE(NULL); } @@ -3706,56 +3671,57 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) */ AActor *target; - fixedvec3 pos; - fixed_t vx, vy, vz; + DVector3 pos; + DVector3 vel; PARAM_ACTION_PROLOGUE; PARAM_STATE (jump); PARAM_INT_OPT (flags) { flags = 0; } PARAM_FLOAT_OPT (range) { range = 0; } PARAM_FLOAT_OPT (minrange) { minrange = 0; } + PARAM_DANGLE_OPT(angle) { angle = 0.; } + PARAM_DANGLE_OPT(pitch) { pitch = 0.; } + PARAM_FLOAT_OPT (offsetheight) { offsetheight = 0; } + PARAM_FLOAT_OPT (offsetwidth) { offsetwidth = 0; } + PARAM_INT_OPT (ptr_target) { ptr_target = AAPTR_DEFAULT; } + PARAM_FLOAT_OPT (offsetforward) { offsetforward = 0; } + + DAngle ang; + + target = COPY_AAPTR(self, ptr_target == AAPTR_DEFAULT ? AAPTR_TARGET|AAPTR_PLAYER_GETTARGET|AAPTR_NULL : ptr_target); // no player-support by default + + if (flags & CLOFF_MUL_HEIGHT) { - PARAM_DANGLE_OPT(angle) { angle = 0.; } - PARAM_DANGLE_OPT(pitch) { pitch = 0.; } - PARAM_FIXED_OPT (offsetheight) { offsetheight = 0; } - PARAM_FIXED_OPT (offsetwidth) { offsetwidth = 0; } - PARAM_INT_OPT (ptr_target) { ptr_target = AAPTR_DEFAULT; } - PARAM_FIXED_OPT (offsetforward) { offsetforward = 0; } - - target = COPY_AAPTR(self, ptr_target == AAPTR_DEFAULT ? AAPTR_TARGET|AAPTR_PLAYER_GETTARGET|AAPTR_NULL : ptr_target); // no player-support by default - - if (flags & CLOFF_MUL_HEIGHT) + if (self->player != NULL) { - if (self->player != NULL) - { - // Synced with hitscan: self->player->mo->_f_height() is strangely conscientious about getting the right actor for player - offsetheight = FixedMul(offsetheight, fixed_t(self->player->mo->_f_height() * self->player->crouchfactor)); - } - else - { - offsetheight = FixedMul(offsetheight, self->_f_height()); - } + // Synced with hitscan: self->player->mo->height is strangely conscientious about getting the right actor for player + offsetheight *= self->player->mo->Height * self->player->crouchfactor; } - if (flags & CLOFF_MUL_WIDTH) + else { - offsetforward = FixedMul(self->_f_radius(), offsetforward); - offsetwidth = FixedMul(self->_f_radius(), offsetwidth); + offsetheight *= self->Height; } + } + if (flags & CLOFF_MUL_WIDTH) + { + offsetforward *= self->radius; + offsetwidth *= self->radius; + } - pos = self->PosPlusZ(offsetheight - self->_f_floorclip()); + pos = self->PosPlusZ(offsetheight - self->Floorclip); if (!(flags & CLOFF_FROMBASE)) { // default to hitscan origin // Synced with hitscan: self->_f_height() is strangely NON-conscientious about getting the right actor for player - pos.z += (self->_f_height() >> 1); + pos.Z += self->Height *0.5; if (self->player != NULL) { - pos.z += FLOAT2FIXED(self->player->mo->AttackZOffset * self->player->crouchfactor); + pos.Z += self->player->mo->AttackZOffset * self->player->crouchfactor; } else { - pos.z += 8*FRACUNIT; + pos.Z += 8; } } @@ -3770,25 +3736,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) } } + if (flags & CLOFF_NOAIM_HORZ) { - DAngle ang; - - if (flags & CLOFF_NOAIM_HORZ) - { - ang = self->Angles.Yaw; - } - else ang = self->AngleTo (target); - - angle += ang; - - double s = ang.Sin(); - double c = ang.Cos(); - - fixedvec2 xy = self->Vec2Offset(fixed_t(offsetforward * c + offsetwidth * s), fixed_t(offsetforward * s - offsetwidth * c)); - - pos.x = xy.x; - pos.y = xy.y; + ang = self->Angles.Yaw; } + else ang = self->AngleTo (target); + + angle += ang; + + double s = ang.Sin(); + double c = ang.Cos(); + + DVector2 xy = self->Vec2Offset(offsetforward * c + offsetwidth * s, offsetforward * s - offsetwidth * c); + + pos.X = xy.X; + pos.Y = xy.Y; double xydist = self->Distance2D(target); if (flags & CLOFF_NOAIM_VERT) @@ -3797,11 +3759,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) } else if (flags & CLOFF_AIM_VERT_NOOFFSET) { - pitch -= VecToAngle(xydist, FIXED2FLOAT(target->_f_Z() - pos.z + offsetheight + target->_f_height() / 2)); + pitch -= VecToAngle(xydist, target->Center() - pos.Z + offsetheight); } else { - pitch -= VecToAngle(xydist, FIXED2FLOAT(target->_f_Z() - pos.z + target->_f_height() / 2)); + pitch -= VecToAngle(xydist, target->Center()); } } else if (flags & CLOFF_ALLOWNULL) @@ -3812,10 +3774,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) double s = angle.Sin(); double c = angle.Cos(); - fixedvec2 xy = self->Vec2Offset(fixed_t(offsetforward * c + offsetwidth * s), fixed_t(offsetforward * s - offsetwidth * c)); + DVector2 xy = self->Vec2Offset(offsetforward * c + offsetwidth * s, offsetforward * s - offsetwidth * c); - pos.x = xy.x; - pos.y = xy.y; + pos.X = xy.X; + pos.Y = xy.Y; } else { @@ -3824,20 +3786,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) double cp = pitch.Cos(); - vx = FLOAT2FIXED(cp * angle.Cos()); - vy = FLOAT2FIXED(cp * angle.Sin()); - vz = FLOAT2FIXED(-pitch.Sin()); - } + vel = { cp * angle.Cos(), cp * angle.Sin(), -pitch.Sin() }; /* Variable set: jump, flags, target - x1,y1,z1 (trace point of origin) - vx,vy,vz (trace unit vector) + pos (trace point of origin) + vel (trace unit vector) range */ - sector_t *sec = P_PointInSector(pos.x, pos.y); + sector_t *sec = P_PointInSector(pos); if (range == 0) { @@ -3852,7 +3811,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) lof_data.Flags = flags; lof_data.BadActor = false; - Trace(pos.x, pos.y, pos.z, sec, vx, vy, vz, FLOAT2FIXED(range), ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, self, trace, TRACE_PortalRestrict, + Trace(pos, sec, vel, range, ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, self, trace, TRACE_PortalRestrict, CheckLOFTraceFunc, &lof_data); if (trace.HitType == TRACE_HitActor || @@ -3909,12 +3868,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) { PARAM_ACTION_PROLOGUE; PARAM_STATE (jump); - PARAM_ANGLE_OPT (fov) { fov = 0; } + PARAM_DANGLE_OPT(fov) { fov = 0.; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (dist_max) { dist_max = 0; } - PARAM_FIXED_OPT (dist_close) { dist_close = 0; } + PARAM_FLOAT_OPT (dist_max) { dist_max = 0; } + PARAM_FLOAT_OPT (dist_close) { dist_close = 0; } - angle_t an; AActor *target, *viewport; FTranslatedLineTarget t; @@ -3964,14 +3922,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) { case JLOSF_TARGETLOS|JLOSF_FLIPFOV: // target makes sight check, player makes fov check; player has verified fov - fov = 0; + fov = 0.; // fall-through case JLOSF_TARGETLOS: doCheckSight = !(flags & JLOSF_NOSIGHT); // The target is responsible for sight check and fov break; default: // player has verified sight and fov - fov = 0; + fov = 0.; // fall-through case JLOSF_FLIPFOV: // Player has verified sight, but target must verify fov doCheckSight = false; @@ -3989,7 +3947,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) { ACTION_RETURN_STATE(NULL); } - fixed_t distance = self->AproxDistance3D(target); + double distance = self->Distance3D(target); if (dist_max && (distance > dist_max)) { @@ -4002,7 +3960,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) ACTION_RETURN_STATE(NULL); } if (flags & JLOSF_CLOSENOFOV) - fov = 0; + fov = 0.; if (flags & JLOSF_CLOSENOSIGHT) doCheckSight = false; @@ -4022,11 +3980,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) else { target = viewport; viewport = self; } } - if (fov && (fov < ANGLE_MAX)) + if (fov > 0 && (fov < 360.)) { - an = viewport->__f_AngleTo(target) - viewport->_f_angle(); + DAngle an = absangle(viewport->AngleTo(target), viewport->Angles.Yaw); - if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) + if (an > (fov / 2)) { ACTION_RETURN_STATE(NULL); // [KS] Outside of FOV - return } @@ -4046,12 +4004,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetLOS) { PARAM_ACTION_PROLOGUE; PARAM_STATE (jump); - PARAM_ANGLE_OPT (fov) { fov = 0; } + PARAM_DANGLE_OPT(fov) { fov = 0.; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (dist_max) { dist_max = 0; } - PARAM_FIXED_OPT (dist_close) { dist_close = 0; } + PARAM_FLOAT_OPT (dist_max) { dist_max = 0; } + PARAM_FLOAT_OPT (dist_close) { dist_close = 0; } - angle_t an; AActor *target; if (flags & JLOSF_CHECKMASTER) @@ -4080,7 +4037,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetLOS) ACTION_RETURN_STATE(NULL); } - fixed_t distance = self->AproxDistance3D(target); + double distance = self->Distance3D(target); if (dist_max && (distance > dist_max)) { @@ -4096,17 +4053,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetLOS) ACTION_RETURN_STATE(NULL); } if (flags & JLOSF_CLOSENOFOV) - fov = 0; + fov = 0.; if (flags & JLOSF_CLOSENOSIGHT) doCheckSight = false; } - if (fov && (fov < ANGLE_MAX)) + if (fov > 0 && (fov < 360.)) { - an = target->__f_AngleTo(self) - target->_f_angle(); + DAngle an = absangle(target->AngleTo(self), target->Angles.Yaw); - if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) + if (an > (fov / 2)) { ACTION_RETURN_STATE(NULL); // [KS] Outside of FOV - return } @@ -4387,8 +4344,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_RaiseSiblings) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_FaceConsolePlayer) { - PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(max_turn_angle) { max_turn_angle = 0; } // NOTE: It does nothing for zdoom. return 0; } @@ -5056,12 +5011,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) PARAM_ACTION_PROLOGUE; PARAM_INT_OPT (flags) { flags = 0; } PARAM_SOUND_OPT (sound) { sound = "weapons/pistol"; } - PARAM_FIXED_OPT (snipe) { snipe = FRACUNIT; } + PARAM_FLOAT_OPT (snipe) { snipe = 1.; } PARAM_INT_OPT (maxdamage) { maxdamage = 64; } PARAM_INT_OPT (blocksize) { blocksize = 128; } PARAM_INT_OPT (pointblank) { pointblank = 2; } PARAM_INT_OPT (longrange) { longrange = 4; } - PARAM_FIXED_OPT (runspeed) { runspeed = 160*FRACUNIT; } + PARAM_FLOAT_OPT (runspeed) { runspeed = 160; } PARAM_CLASS_OPT (pufftype, AActor) { pufftype = PClass::FindActor(NAME_BulletPuff); } if (!self->target) @@ -5074,31 +5029,27 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) A_FaceTarget (self); // Target can dodge if it can see enemy - angle_t angle = self->target->__f_AngleTo(self) - self->target->_f_angle(); - angle >>= 24; - bool dodge = (P_CheckSight(self->target, self) && (angle>226 || angle<30)); + DAngle angle = absangle(self->target->Angles.Yaw, self->target->AngleTo(self)); + bool dodge = (P_CheckSight(self->target, self) && angle < 30. * 256. / 360.); // 30 byteangles ~ 21° // Distance check is simplistic - fixedvec2 vec = self->_f_Vec2To(self->target); - fixed_t dx = abs (vec.x); - fixed_t dy = abs (vec.y); - fixed_t dist = dx > dy ? dx : dy; + DVector2 vec = self->Vec2To(self->target); + double dx = fabs (vec.X); + double dy = fabs (vec.Y); + double dist = dx > dy ? dx : dy; // Some enemies are more precise - dist = FixedMul(dist, snipe); + dist *= snipe; // Convert distance into integer number of blocks - dist >>= FRACBITS; - dist /= blocksize; + int idist = int(dist / blocksize); // Now for the speed accuracy thingie - fixed_t speed = FixedMul(self->target->_f_velx(), self->target->_f_velx()) - + FixedMul(self->target->_f_vely(), self->target->_f_vely()) - + FixedMul(self->target->_f_velz(), self->target->_f_velz()); + double speed = self->target->Vel.LengthSquared(); int hitchance = speed < runspeed ? 256 : 160; // Distance accuracy (factoring dodge) - hitchance -= dist * (dodge ? 16 : 8); + hitchance -= idist * (dodge ? 16 : 8); // While we're here, we may as well do something for this: if (self->target->flags & MF_SHADOW) @@ -5110,9 +5061,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) if (pr_cabullet() < hitchance) { // Compute position for spawning blood/puff - angle = self->target->__f_AngleTo(self); - - DVector3 BloodPos = self->target->Vec3Angle(self->target->radius, ANGLE2DBL(angle), self->target->Height/2); + DAngle angle = self->target->AngleTo(self); + DVector3 BloodPos = self->target->Vec3Angle(self->target->radius, angle, self->target->Height/2); int damage = flags & WAF_NORANDOM ? maxdamage : (1 + (pr_cabullet() % maxdamage)); if (dist >= pointblank) @@ -5133,7 +5083,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) if ((0 && dpuff->flags3 & MF3_PUFFONACTORS) || !spawnblood) { spawnblood = false; - P_SpawnPuff(self, pufftype, BloodPos, ANGLE2DBL(angle), ANGLE2DBL(angle), 0); + P_SpawnPuff(self, pufftype, BloodPos, angle, angle, 0); } } else if (self->target->flags3 & MF3_GHOST) @@ -5143,7 +5093,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) int newdam = P_DamageMobj(self->target, self, self, damage, mod, DMG_THRUSTLESS); if (spawnblood) { - P_SpawnBlood(BloodPos, ANGLE2DBL(angle), newdam > 0 ? newdam : damage, self->target); + P_SpawnBlood(BloodPos, angle, newdam > 0 ? newdam : damage, self->target); P_TraceBleed(newdam > 0 ? newdam : damage, self->target, self); } } @@ -5165,15 +5115,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) { PARAM_ACTION_PROLOGUE; PARAM_INT(destination_selector); - PARAM_FIXED_OPT(xofs) { xofs = 0; } - PARAM_FIXED_OPT(yofs) { yofs = 0; } - PARAM_FIXED_OPT(zofs) { zofs = 0; } - PARAM_ANGLE_OPT(angle) { angle = 0; } + PARAM_FLOAT_OPT(xofs) { xofs = 0; } + PARAM_FLOAT_OPT(yofs) { yofs = 0; } + PARAM_FLOAT_OPT(zofs) { zofs = 0; } + PARAM_DANGLE_OPT(angle) { angle = 0.; } PARAM_INT_OPT(flags) { flags = 0; } PARAM_STATE_OPT(success_state) { success_state = NULL; } - PARAM_FIXED_OPT(heightoffset) { heightoffset = 0; } - PARAM_FIXED_OPT(radiusoffset) { radiusoffset = 0; } - PARAM_ANGLE_OPT(pitch) { pitch = 0; } + PARAM_FLOAT_OPT(heightoffset) { heightoffset = 0; } + PARAM_FLOAT_OPT(radiusoffset) { radiusoffset = 0; } + PARAM_DANGLE_OPT(pitch) { pitch = 0.; } AActor *reference; @@ -5374,7 +5324,7 @@ enum RadiusGiveFlags RGF_CORPSES | RGF_MISSILES, }; -static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amount, fixed_t distance, int flags, PClassActor *filter, FName species, fixed_t mindist) +static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amount, double distance, int flags, PClassActor *filter, FName species, double mindist) { // [MC] We only want to make an exception for missiles here. Nothing else. bool missilePass = !!((flags & RGF_MISSILES) && thing->flags & MF_MISSILE); @@ -5448,26 +5398,22 @@ static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amo if (selfPass || monsterPass || corpsePass || killedPass || itemPass || objectPass || missilePass || playerPass || voodooPass) { - fixedvec3 diff = self->_f_Vec3To(thing); - diff.z += (thing->_f_height() - self->_f_height()) / 2; + DVector3 diff = self->Vec3To(thing); + diff.Z += thing->Height *0.5; if (flags & RGF_CUBE) { // check if inside a cube - double dx = fabs((double)(diff.x)); - double dy = fabs((double)(diff.y)); - double dz = fabs((double)(diff.z)); - double dist = (double)distance; - double min = (double)mindist; - if ((dx > dist || dy > dist || dz > dist) || (min && (dx < min && dy < min && dz < min))) + double dx = fabs(diff.X); + double dy = fabs(diff.Y); + double dz = fabs(diff.Z); + if ((dx > distance || dy > distance || dz > distance) || (mindist && (dx < mindist && dy < mindist && dz < mindist))) { return false; } } else { // check if inside a sphere - double distsquared = double(distance) * double(distance); - double minsquared = double(mindist) * double(mindist); - double lengthsquared = DVector3(diff.x, diff.y, diff.z).LengthSquared(); - if (lengthsquared > distsquared || (minsquared && (lengthsquared < minsquared))) + double lengthsquared = diff.LengthSquared(); + if (lengthsquared > distance*distance || (mindist && (lengthsquared < mindist*mindist))) { return false; } @@ -5504,12 +5450,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (item, AInventory); - PARAM_FIXED (distance); + PARAM_FLOAT (distance); PARAM_INT (flags); PARAM_INT_OPT (amount) { amount = 0; } PARAM_CLASS_OPT (filter, AActor) { filter = NULL; } PARAM_NAME_OPT (species) { species = NAME_None; } - PARAM_FIXED_OPT (mindist) { mindist = 0; } + PARAM_FLOAT_OPT (mindist) { mindist = 0; } // We need a valid item, valid targets, and a valid range if (item == NULL || (flags & RGF_MASK) == 0 || !flags || distance <= 0 || mindist >= distance) @@ -5534,8 +5480,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) else { FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); - fixed_t mid = self->_f_Z() + self->_f_height() / 2; - FMultiBlockThingsIterator it(check, self->_f_X(), self->_f_Y(), mid-distance, mid+distance, distance, false, self->Sector); + double mid = self->Center(); + FMultiBlockThingsIterator it(check, self->X(), self->Y(), mid-distance, mid+distance, distance, false, self->Sector); FMultiBlockThingsIterator::CheckResult cres; while ((it.Next(&cres))) @@ -6356,8 +6302,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHigherOrLower) PARAM_ACTION_PROLOGUE; PARAM_STATE(high); PARAM_STATE(low); - PARAM_FIXED_OPT(offsethigh) { offsethigh = 0; } - PARAM_FIXED_OPT(offsetlow) { offsetlow = 0; } + PARAM_FLOAT_OPT(offsethigh) { offsethigh = 0; } + PARAM_FLOAT_OPT(offsetlow) { offsetlow = 0; } PARAM_BOOL_OPT(includeHeight) { includeHeight = true; } PARAM_INT_OPT(ptr) { ptr = AAPTR_TARGET; } @@ -6366,11 +6312,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHigherOrLower) if (mobj != NULL && mobj != self) //AAPTR_DEFAULT is completely useless in this regard. { - if ((high) && (mobj->_f_Z() > ((includeHeight ? self->_f_height() : 0) + self->_f_Z() + offsethigh))) + if ((high) && (mobj->Z() > ((includeHeight ? self->Height : 0) + self->Z() + offsethigh))) { ACTION_RETURN_STATE(high); } - else if ((low) && (mobj->_f_Z() + (includeHeight ? mobj->_f_height() : 0)) < (self->_f_Z() + offsetlow)) + else if ((low) && (mobj->Z() + (includeHeight ? mobj->Height : 0)) < (self->Z() + offsetlow)) { ACTION_RETURN_STATE(low); } @@ -6497,7 +6443,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) PARAM_ACTION_PROLOGUE; PARAM_STATE(jump); PARAM_CLASS(classname, AActor); - PARAM_FIXED(distance); + PARAM_FLOAT(distance); PARAM_INT_OPT(count) { count = 1; } PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } @@ -6518,7 +6464,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) } int counter = 0; bool result = false; - fixed_t closer = distance, farther = 0, current = distance; + double closer = distance, farther = 0, current = distance; const bool ptrWillChange = !!(flags & (CPXF_SETTARGET | CPXF_SETMASTER | CPXF_SETTRACER)); const bool ptrDistPref = !!(flags & (CPXF_CLOSEST | CPXF_FARTHEST)); @@ -6549,10 +6495,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) //[MC]Make sure it's in range and respect the desire for Z or not. The function forces it to use //Z later for ensuring CLOSEST and FARTHEST flags are respected perfectly. //Ripped from sphere checking in A_RadiusGive (along with a number of things). - if ((ref->AproxDistance(mo) < distance && + if ((ref->Distance2D(mo) < distance && ((flags & CPXF_NOZ) || - ((ref->_f_Z() > mo->_f_Z() && ref->_f_Z() - mo->_f_Top() < distance) || - (ref->_f_Z() <= mo->_f_Z() && mo->_f_Z() - ref->_f_Top() < distance))))) + ((ref->Z() > mo->Z() && ref->Z() - mo->Top() < distance) || + (ref->Z() <= mo->Z() && mo->Z() - ref->Top() < distance))))) { if ((flags & CPXF_CHECKSIGHT) && !(P_CheckSight(mo, ref, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))) continue; @@ -6656,10 +6602,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) PARAM_STATE(block) PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } - PARAM_FIXED_OPT(xofs) { xofs = 0; } - PARAM_FIXED_OPT(yofs) { yofs = 0; } - PARAM_FIXED_OPT(zofs) { zofs = 0; } - PARAM_ANGLE_OPT(angle) { angle = 0; } + PARAM_FLOAT_OPT(xofs) { xofs = 0; } + PARAM_FLOAT_OPT(yofs) { yofs = 0; } + PARAM_FLOAT_OPT(zofs) { zofs = 0; } + PARAM_DANGLE_OPT(angle) { angle = 0.; } AActor *mobj = COPY_AAPTR(self, ptr); @@ -6669,28 +6615,23 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) ACTION_RETURN_STATE(NULL); } -#if 0 // this needs some work. if (!(flags & CBF_ABSOLUTEANGLE)) { - angle += self->angle; + angle += self->Angles.Yaw; } - angle_t ang = angle >> ANGLETOFINESHIFT; - fixedvec3 oldpos = mobj->Pos(); - fixedvec3 pos; + DVector3 oldpos = mobj->Pos(); + DVector3 pos; if (flags & CBF_ABSOLUTEPOS) { - pos.x = xofs; - pos.y = yofs; - pos.z = zofs; + pos = { xofs, yofs, zofs }; } else { - pos = mobj->Vec3Offset( - FixedMul(xofs, finecosine[ang]) + FixedMul(yofs, finesine[ang]), - FixedMul(xofs, finesine[ang]) - FixedMul(yofs, finecosine[ang]), - mobj->Z() + zofs); + double s = angle.Sin(); + double c = angle.Cos(); + pos = mobj->Vec3Offset(xofs * c + yofs * s, xofs * s - yofs * c, zofs); } // Next, try checking the position based on the sensitivity desired. @@ -6700,9 +6641,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) bool checker = false; if (flags & CBF_DROPOFF) { - mobj->SetZ(pos.z); - checker = P_CheckMove(mobj, pos.x, pos.y); - mobj->SetZ(oldpos.z); + mobj->SetZ(pos.Z); + checker = P_CheckMove(mobj, pos.X, pos.Y); + mobj->SetZ(oldpos.Z); } else { @@ -6710,10 +6651,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) checker = P_TestMobjLocation(mobj); mobj->SetOrigin(oldpos, true); } -#endif - //Nothing to block it so skip the rest. - bool checker = (flags & CBF_DROPOFF) ? P_CheckMove(mobj, mobj->_f_X(), mobj->_f_Y()) : P_TestMobjLocation(mobj); if (checker) { ACTION_RETURN_STATE(NULL); @@ -6762,9 +6700,9 @@ enum FMDFlags DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(offset) { offset = 0; } - PARAM_ANGLE_OPT(anglelimit) { anglelimit = 0; } - PARAM_ANGLE_OPT(pitchlimit) { pitchlimit = 0; } + PARAM_DANGLE_OPT(offset) { offset = 0.; } + PARAM_DANGLE_OPT(anglelimit) { anglelimit = 0.; } + PARAM_DANGLE_OPT(pitchlimit) { pitchlimit = 0.; } PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } @@ -6779,78 +6717,65 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection) //Don't bother calculating this if we don't have any horizontal movement. if (!(flags & FMDF_NOANGLE) && (mobj->Vel.X != 0 || mobj->Vel.Y != 0)) { - angle_t current = mobj->_f_angle(); - const angle_t angle = R_PointToAngle2(0, 0, mobj->_f_velx(), mobj->_f_vely()); + DAngle current = mobj->Angles.Yaw; + DAngle angle = mobj->Vel.Angle(); //Done because using anglelimit directly causes a signed/unsigned mismatch. - const angle_t limit = anglelimit; //Code borrowed from A_Face*. - if (limit > 0 && (absangle(current - angle) > limit)) + if (anglelimit > 0) { - if (current < angle) + DAngle delta = deltaangle(current, angle); + if (fabs(delta) > anglelimit) { - // [MC] This may appear backwards, but I assure any who - // reads this, it works. - if (current - angle > ANGLE_180) - current += limit + offset; - else - current -= limit + offset; - mobj->SetAngle(ANGLE2DBL(current), !!(flags & FMDF_INTERPOLATE)); + if (delta < 0) + { + current += anglelimit + offset; + } + else if (delta > 0) + { + current -= anglelimit + offset; + } + else // huh??? + { + current = angle + 180. + offset; + } + mobj->SetAngle(current, !!(flags & FMDF_INTERPOLATE)); } - else if (current > angle) - { - if (angle - current > ANGLE_180) - current -= limit + offset; - else - current += limit + offset; - mobj->SetAngle(ANGLE2DBL(current), !!(flags & FMDF_INTERPOLATE)); - } - else - mobj->SetAngle(ANGLE2DBL(angle + ANGLE_180 + offset), !!(flags & FMDF_INTERPOLATE)); } else - mobj->SetAngle(ANGLE2DBL(angle + offset), !!(flags & FMDF_INTERPOLATE)); + mobj->SetAngle(angle + offset, !!(flags & FMDF_INTERPOLATE)); } if (!(flags & FMDF_NOPITCH)) { - fixed_t current = mobj->_f_pitch(); - const DVector2 velocity(mobj->_f_velx(), mobj->_f_vely()); - const fixed_t pitch = R_PointToAngle2(0, 0, xs_CRoundToInt(velocity.Length()), -mobj->_f_velz()); + DAngle current = mobj->Angles.Pitch; + const DVector2 velocity = mobj->Vel.XY(); + DAngle pitch = VecToAngle(velocity.Length(), -mobj->Vel.Z); if (pitchlimit > 0) { - // [MC] angle_t for pitchlimit was required because otherwise - // we would wind up with less than desirable turn rates that didn't - // match that of A_SetPitch. We want consistency. Also, I didn't know - // of a better way to convert from angle_t to fixed_t properly so I - // used this instead. - fixed_t plimit = fixed_t(pitchlimit); + DAngle pdelta = deltaangle(current, pitch); - if (abs(current - pitch) > plimit) + if (fabs(pdelta) > pitchlimit) { - fixed_t max = 0; - - if (current > pitch) + if (pdelta > 0) { - max = MIN(plimit, (current - pitch)); - current -= max; + current -= MIN(pitchlimit, pdelta); } - else //if (current > pitch) + else //if (pdelta < 0) { - max = MIN(plimit, (pitch - current)); - current += max; + current += MIN(pitchlimit, -pdelta); } - mobj->SetPitch(ANGLE2DBL(current), !!(flags & FMDF_INTERPOLATE)); + mobj->SetPitch(current, !!(flags & FMDF_INTERPOLATE)); } else { - mobj->SetPitch(ANGLE2DBL(pitch), !!(flags & FMDF_INTERPOLATE)); + mobj->SetPitch(pitch, !!(flags & FMDF_INTERPOLATE)); } } else { - mobj->SetPitch(ANGLE2DBL(pitch), !!(flags & FMDF_INTERPOLATE)); + mobj->SetPitch(pitch, !!(flags & FMDF_INTERPOLATE)); } } ACTION_RETURN_BOOL(true); diff --git a/src/zscript/vm.h b/src/zscript/vm.h index 1f5c8d95b..e4cc81310 100644 --- a/src/zscript/vm.h +++ b/src/zscript/vm.h @@ -894,8 +894,6 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_SOUND_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); FSoundID x = param[p].i; #define PARAM_COLOR_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); PalEntry x; x.d = param[p].i; #define PARAM_FLOAT_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); double x = param[p].f; -#define PARAM_FIXED_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); fixed_t x = FLOAT2FIXED(param[p].f); -#define PARAM_ANGLE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); angle_t x = FLOAT2ANGLE(param[p].f); #define PARAM_DANGLE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); DAngle x = param[p].f; #define PARAM_STRING_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_STRING); FString x = param[p].s(); #define PARAM_STATE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].a == NULL)); FState *x = (FState *)param[p].a; @@ -913,8 +911,6 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_SOUND_OPT_AT(p,x) FSoundID x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x = FSoundID(param[p].i); } else #define PARAM_COLOR_OPT_AT(p,x) PalEntry x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x.d = param[p].i; } else #define PARAM_FLOAT_OPT_AT(p,x) double x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else -#define PARAM_FIXED_OPT_AT(p,x) fixed_t x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = FLOAT2FIXED(param[p].f); } else -#define PARAM_ANGLE_OPT_AT(p,x) angle_t x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = FLOAT2ANGLE(param[p].f); } else #define PARAM_DANGLE_OPT_AT(p,x) DAngle x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else #define PARAM_STRING_OPT_AT(p,x) FString x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_STRING); x = param[p].s(); } else #define PARAM_STATE_OPT_AT(p,x) FState *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].a == NULL)); x = (FState *)param[p].a; } else @@ -931,8 +927,6 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_SOUND(x) ++paramnum; PARAM_SOUND_AT(paramnum,x) #define PARAM_COLOR(x) ++paramnum; PARAM_COLOR_AT(paramnum,x) #define PARAM_FLOAT(x) ++paramnum; PARAM_FLOAT_AT(paramnum,x) -#define PARAM_FIXED(x) ++paramnum; PARAM_FIXED_AT(paramnum,x) -#define PARAM_ANGLE(x) ++paramnum; PARAM_ANGLE_AT(paramnum,x) #define PARAM_DANGLE(x) ++paramnum; PARAM_DANGLE_AT(paramnum,x) #define PARAM_STRING(x) ++paramnum; PARAM_STRING_AT(paramnum,x) #define PARAM_STATE(x) ++paramnum; PARAM_STATE_AT(paramnum,x) @@ -946,8 +940,6 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_SOUND_OPT(x) ++paramnum; PARAM_SOUND_OPT_AT(paramnum,x) #define PARAM_COLOR_OPT(x) ++paramnum; PARAM_COLOR_OPT_AT(paramnum,x) #define PARAM_FLOAT_OPT(x) ++paramnum; PARAM_FLOAT_OPT_AT(paramnum,x) -#define PARAM_FIXED_OPT(x) ++paramnum; PARAM_FIXED_OPT_AT(paramnum,x) -#define PARAM_ANGLE_OPT(x) ++paramnum; PARAM_ANGLE_OPT_AT(paramnum,x) #define PARAM_DANGLE_OPT(x) ++paramnum; PARAM_DANGLE_OPT_AT(paramnum,x) #define PARAM_STRING_OPT(x) ++paramnum; PARAM_STRING_OPT_AT(paramnum,x) #define PARAM_STATE_OPT(x) ++paramnum; PARAM_STATE_OPT_AT(paramnum,x)