diff --git a/src/actor.h b/src/actor.h index e0043aaa2..dc7013865 100644 --- a/src/actor.h +++ b/src/actor.h @@ -828,16 +828,6 @@ public: return P_AproxDistance(_f_X() - otherx, _f_Y() - othery); } - fixed_t __f_AngleTo(fixed_t otherx, fixed_t othery) - { - return R_PointToAngle2(_f_X(), _f_Y(), otherx, othery); - } - - fixed_t __f_AngleTo(fixedvec2 other) - { - return R_PointToAngle2(_f_X(), _f_Y(), other.x, other.y); - } - // 'absolute' is reserved for a linked portal implementation which needs // to distinguish between portal-aware and portal-unaware distance calculation. fixed_t AproxDistance(AActor *other, bool absolute = false) @@ -846,13 +836,14 @@ public: return P_AproxDistance(_f_X() - otherpos.x, _f_Y() - otherpos.y); } + /* fixed_t AproxDistance(AActor *other, fixed_t xadd, fixed_t yadd, bool absolute = false) { fixedvec3 otherpos = absolute ? other->_f_Pos() : other->_f_PosRelative(this); return P_AproxDistance(_f_X() - otherpos.x + xadd, _f_Y() - otherpos.y + yadd); } + */ - // more precise, but slower version, being used in a few places double Distance2D(AActor *other, bool absolute = false) { DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); @@ -864,6 +855,13 @@ public: return DVector2(X() - x, Y() - y).Length(); } + double Distance2D(AActor *other, double xadd, double yadd, bool absolute = false) + { + DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return DVector2(X() - otherpos.X + xadd, Y() - otherpos.Y + yadd).Length(); + } + + // a full 3D version of the above double Distance3D(AActor *other, bool absolute = false) { @@ -871,17 +869,6 @@ public: return (Pos() - otherpos).Length(); } - angle_t __f_AngleTo(AActor *other, bool absolute = false) - { - fixedvec3 otherpos = absolute ? other->_f_Pos() : other->_f_PosRelative(this); - return R_PointToAngle2(_f_X(), _f_Y(), otherpos.x, otherpos.y); - } - - angle_t __f_AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const - { - return R_PointToAngle2(_f_X(), _f_Y(), other->_f_X() + oxofs, other->_f_Y() + oyofs); - } - DAngle AngleTo(AActor *other, bool absolute = false) { DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); @@ -1064,6 +1051,10 @@ public: SetOrigin(npos.x, npos.y, npos.z, moving); } + void Move(const DVector3 &vel) + { + SetOrigin(Pos() + vel, true); + } void SetOrigin(double x, double y, double z, bool moving) { SetOrigin(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(z), moving); diff --git a/src/am_map.cpp b/src/am_map.cpp index ca1d3fc2b..1189ec3a7 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -815,7 +815,7 @@ CVAR(Bool, am_portaloverlay, true, CVAR_ARCHIVE) CCMD(am_togglefollow) { am_followplayer = !am_followplayer; - f_oldloc.x = FIXED_MAX; + f_oldloc.x = FLT_MAX; Printf ("%s\n", GStrings(am_followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF")); } @@ -1022,7 +1022,7 @@ bool AM_addMark () static void AM_findMinMaxBoundaries () { - min_x = min_y = FIXED_MAX; + min_x = min_y = FLT_MAX; max_x = max_y = FIXED_MIN; for (int i = 0; i < numvertexes; i++) @@ -1094,7 +1094,7 @@ static void AM_ClipRotatedExtents (double pivotx, double pivoty) xs[2] = max_x; ys[2] = max_y; xs[3] = min_x; ys[3] = max_y; xs[4] = m_x + m_w/2; ys[4] = m_y + m_h/2; - rmin_x = rmin_y = FIXED_MAX; + rmin_x = rmin_y = FLT_MAX; rmax_x = rmax_y = FIXED_MIN; for (i = 0; i < 5; ++i) @@ -1175,7 +1175,7 @@ void AM_changeWindowLoc () if (m_paninc.x || m_paninc.y) { am_followplayer = false; - f_oldloc.x = FIXED_MAX; + f_oldloc.x = FLT_MAX; } double oldmx = m_x, oldmy = m_y; @@ -1220,7 +1220,7 @@ void AM_initVariables () Button_AM_ZoomOut.Reset(); - f_oldloc.x = FIXED_MAX; + f_oldloc.x = FLT_MAX; amclock = 0; m_paninc.x = m_paninc.y = 0; diff --git a/src/b_bot.cpp b/src/b_bot.cpp index 3d6c916c6..a4160b92c 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -33,7 +33,7 @@ DBot::DBot () void DBot::Clear () { player = NULL; - angle = 0; + Angle = 0.; dest = NULL; prev = NULL; enemy = NULL; @@ -52,27 +52,15 @@ void DBot::Clear () sleft = false; allround = false; increase = false; - oldx = 0; - oldy = 0; + old = { 0, 0 }; } void DBot::Serialize (FArchive &arc) { Super::Serialize (arc); - if (SaveVersion < 4515) - { - angle_t savedyaw; - int savedpitch; - arc << savedyaw - << savedpitch; - } - else - { - arc << player; - } - - arc << angle + arc << player + << Angle << dest << prev << enemy @@ -91,8 +79,7 @@ void DBot::Serialize (FArchive &arc) << sleft << allround << increase - << oldx - << oldy; + << old; } void DBot::Tick () diff --git a/src/b_bot.h b/src/b_bot.h index 5b8e48c8f..e56b03f00 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -31,18 +31,18 @@ #define BOTFILENAME "bots.cfg" -#define MAX_TRAVERSE_DIST 100000000 //10 meters, used within b_func.c -#define AVOID_DIST 45000000 //Try avoid incoming missiles once they reached this close -#define SAFE_SELF_MISDIST (140*FRACUNIT) //Distance from self to target where it's safe to pull a rocket. -#define FRIEND_DIST 15000000 //To friend. -#define DARK_DIST 5000000 //Distance that bot can see enemies in the dark from. +#define MAX_TRAVERSE_DIST (100000000/65536.) //10 meters, used within b_func.c +#define AVOID_DIST (45000000/65536.) //Try avoid incoming missiles once they reached this close +#define SAFE_SELF_MISDIST (140.) //Distance from self to target where it's safe to pull a rocket. +#define FRIEND_DIST (15000000/65536.) //To friend. +#define DARK_DIST (5000000/65536.) //Distance that bot can see enemies in the dark from. #define WHATS_DARK 50 //light value thats classed as dark. -#define MAX_MONSTER_TARGET_DIST 50000000 //Too high can slow down the performance, see P_mobj.c -#define ENEMY_SCAN_FOV (120*ANGLE_1) +#define MAX_MONSTER_TARGET_DIST (50000000/65536.) //Too high can slow down the performance, see P_mobj.c +#define ENEMY_SCAN_FOV (120.) #define THINGTRYTICK 1000 -#define MAXMOVEHEIGHT (32*FRACUNIT) //MAXSTEPMOVE but with jumping counted in. -#define GETINCOMBAT 35000000 //Max distance to item. if it's due to be icked up in a combat situation. -#define SHOOTFOV (60*ANGLE_1) +#define MAXMOVEHEIGHT (32) //MAXSTEPMOVE but with jumping counted in. +#define GETINCOMBAT (35000000/65536.) //Max distance to item. if it's due to be icked up in a combat situation. +#define SHOOTFOV (60.) #define AFTERTICS (2*TICRATE) //Seconds that bot will be alert on an recent enemy. Ie not looking the other way #define MAXROAM (4*TICRATE) //When this time is elapsed the bot will roam after something else. //monster mod @@ -104,11 +104,11 @@ public: void FinishTravel (); bool IsLeader (player_t *player); void SetBodyAt (const DVector3 &pos, int hostnum); - fixed_t FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd); - bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm); + double FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd); + bool SafeCheckPosition (AActor *actor, double x, double y, FCheckPosition &tm); //(b_move.cpp) - bool CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cmd); + bool CleanAhead (AActor *thing, double x, double y, ticcmd_t *cmd); bool IsDangerous (sector_t *sec); TArray getspawned; //Array of bots (their names) which should be spawned when starting a game. @@ -149,10 +149,10 @@ public: void WhatToGet (AActor *item); //(b_func.cpp) - bool Check_LOS (AActor *to, angle_t vangle); + bool Check_LOS (AActor *to, DAngle vangle); player_t *player; - angle_t angle; // The wanted angle that the bot try to get every tic. + DAngle Angle; // The wanted angle that the bot try to get every tic. // (used to get a smooth view movement) TObjPtr dest; // Move Destination. TObjPtr prev; // Previous move destination. @@ -183,8 +183,7 @@ public: bool allround; bool increase; - fixed_t oldx; - fixed_t oldy; + DVector2 old; private: //(b_think.cpp) @@ -197,7 +196,7 @@ private: void Dofire (ticcmd_t *cmd); AActor *Choose_Mate (); AActor *Find_enemy (); - angle_t FireRox (AActor *enemy, ticcmd_t *cmd); + DAngle FireRox (AActor *enemy, ticcmd_t *cmd); //(b_move.cpp) void Roam (ticcmd_t *cmd); diff --git a/src/b_func.cpp b/src/b_func.cpp index 803643cea..0e36d93d6 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -34,32 +34,32 @@ bool DBot::Reachable (AActor *rtarget) if (player->mo == rtarget) return false; - if ((rtarget->Sector->ceilingplane.ZatPoint (rtarget) - - rtarget->Sector->floorplane.ZatPoint (rtarget)) - < player->mo->_f_height()) //Where rtarget is, player->mo can't be. + if ((rtarget->Sector->ceilingplane.ZatPointF (rtarget) - + rtarget->Sector->floorplane.ZatPointF (rtarget)) + < player->mo->Height) //Where rtarget is, player->mo can't be. return false; sector_t *last_s = player->mo->Sector; - fixed_t last_z = last_s->floorplane.ZatPoint (player->mo); - fixed_t estimated_dist = player->mo->AproxDistance(rtarget); + double last_z = last_s->floorplane.ZatPointF (player->mo); + double estimated_dist = player->mo->Distance2D(rtarget); bool reachable = true; - FPathTraverse it(player->mo->_f_X()+player->mo->_f_velx(), player->mo->_f_Y()+player->mo->_f_vely(), rtarget->_f_X(), rtarget->_f_Y(), PT_ADDLINES|PT_ADDTHINGS); + FPathTraverse it(player->mo->X()+player->mo->Vel.X, player->mo->Y()+player->mo->Vel.Y, rtarget->X(), rtarget->Y(), PT_ADDLINES|PT_ADDTHINGS); intercept_t *in; while ((in = it.Next())) { - fixed_t hitx, hity; - fixed_t frac; + double hitx, hity; + double frac; line_t *line; AActor *thing; - fixed_t dist; + double dist; sector_t *s; - frac = in->frac - FixedDiv (4*FRACUNIT, MAX_TRAVERSE_DIST); - dist = FixedMul (frac, MAX_TRAVERSE_DIST); + frac = in->Frac - 4 /MAX_TRAVERSE_DIST; + dist = frac * MAX_TRAVERSE_DIST; - hitx = it.Trace().x + FixedMul (player->mo->_f_velx(), frac); - hity = it.Trace().y + FixedMul (player->mo->_f_vely(), frac); + hitx = it.Trace().x + player->mo->Vel.X * frac; + hity = it.Trace().y + player->mo->Vel.Y * frac; if (in->isaline) { @@ -73,13 +73,13 @@ bool DBot::Reachable (AActor *rtarget) { //Determine if going to use backsector/frontsector. s = (line->backsector == last_s) ? line->frontsector : line->backsector; - fixed_t ceilingheight = s->ceilingplane.ZatPoint (hitx, hity); - fixed_t floorheight = s->floorplane.ZatPoint (hitx, hity); + double ceilingheight = s->ceilingplane.ZatPoint (hitx, hity); + double floorheight = s->floorplane.ZatPoint (hitx, hity); if (!bglobal.IsDangerous (s) && //Any nukage/lava? (floorheight <= (last_z+MAXMOVEHEIGHT) && ((ceilingheight == floorheight && line->special) - || (ceilingheight - floorheight) >= player->mo->_f_height()))) //Does it fit? + || (ceilingheight - floorheight) >= player->mo->Height))) //Does it fit? { last_z = floorheight; last_s = s; @@ -100,7 +100,7 @@ bool DBot::Reachable (AActor *rtarget) thing = in->d.thing; if (thing == player->mo) //Can't reach self in this case. continue; - if (thing == rtarget && (rtarget->Sector->floorplane.ZatPoint (rtarget) <= (last_z+MAXMOVEHEIGHT))) + if (thing == rtarget && (rtarget->Sector->floorplane.ZatPointF (rtarget) <= (last_z+MAXMOVEHEIGHT))) { return true; } @@ -118,16 +118,16 @@ bool DBot::Reachable (AActor *rtarget) //if these conditions are true, the function returns true. //GOOD TO KNOW is that the player's view angle //in doom is 90 degrees infront. -bool DBot::Check_LOS (AActor *to, angle_t vangle) +bool DBot::Check_LOS (AActor *to, DAngle vangle) { if (!P_CheckSight (player->mo, to, SF_SEEPASTBLOCKEVERYTHING)) return false; // out of sight - if (vangle == ANGLE_MAX) + if (vangle >= 360.) return true; if (vangle == 0) return false; //Looker seems to be blind. - return absangle(player->mo->AngleTo(to), player->mo->Angles.Yaw) <= ANGLE2FLOAT(vangle/2); + return absangle(player->mo->AngleTo(to), player->mo->Angles.Yaw) <= (vangle/2); } //------------------------------------- @@ -140,10 +140,9 @@ void DBot::Dofire (ticcmd_t *cmd) bool no_fire; //used to prevent bot from pumping rockets into nearby walls. int aiming_penalty=0; //For shooting at shading target, if screen is red, MAKEME: When screen red. int aiming_value; //The final aiming value. - fixed_t dist; - double fdist; - angle_t an; - int m; + double Dist; + DAngle an; + DAngle m; double fm; if (!enemy || !(enemy->flags & MF_SHOOTABLE) || enemy->health <= 0) @@ -172,7 +171,7 @@ void DBot::Dofire (ticcmd_t *cmd) no_fire = true; //Distance to enemy. - dist = player->mo->AproxDistance(enemy, player->mo->_f_velx() - enemy->_f_velx(), player->mo->_f_vely() - enemy->_f_vely()); + Dist = player->mo->Distance2D(enemy, player->mo->Vel.X - enemy->Vel.X, player->mo->Vel.Y - enemy->Vel.Y); //FIRE EACH TYPE OF WEAPON DIFFERENT: Here should all the different weapons go. if (player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON) @@ -194,7 +193,7 @@ void DBot::Dofire (ticcmd_t *cmd) else { //*4 is for atmosphere, the chainsaws sounding and all.. - no_fire = (dist > (FLOAT2FIXED(MELEERANGE)*4)); + no_fire = (Dist > MELEERANGE*4); } } else if (player->ReadyWeapon->WeaponFlags & WIF_BOT_BFG) @@ -210,11 +209,11 @@ void DBot::Dofire (ticcmd_t *cmd) { //Special rules for RL an = FireRox (enemy, cmd); - if(an) + if(an != 0) { - angle = an; + Angle = an; //have to be somewhat precise. to avoid suicide. - if (absangle(angle - player->mo->_f_angle()) < 12*ANGLE_1) + if (absangle(an, player->mo->Angles.Yaw) < 12.) { t_rocket = 9; no_fire = false; @@ -223,17 +222,17 @@ void DBot::Dofire (ticcmd_t *cmd) } // prediction aiming shootmissile: - fdist = player->mo->Distance2D(enemy); - fm = fdist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed; + Dist = player->mo->Distance2D(enemy); + fm = Dist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed; bglobal.SetBodyAt(enemy->Pos() + enemy->Vel.XY() * fm * 2, 1); - angle = player->mo->__f_AngleTo(bglobal.body1); + Angle = player->mo->AngleTo(bglobal.body1); if (Check_LOS (enemy, SHOOTFOV)) no_fire = false; } else { //Other weapons, mostly instant hit stuff. - angle = player->mo->__f_AngleTo(enemy); + Angle = player->mo->AngleTo(enemy); aiming_penalty = 0; if (enemy->flags & MF_SHADOW) aiming_penalty += (pr_botdofire()%25)+10; @@ -246,17 +245,17 @@ shootmissile: aiming_value = 1; m = ((SHOOTFOV/2)-(aiming_value*SHOOTFOV/200)); //Higher skill is more accurate if (m <= 0) - m = 1; //Prevents lock. + m = 1.; //Prevents lock. - if (m) + if (m != 0) { if (increase) - angle += m; + Angle += m; else - angle -= m; + Angle -= m; } - if (absangle(angle - player->mo->_f_angle()) < 4*ANGLE_1) + if (absangle(Angle, player->mo->Angles.Yaw) < 4.) { increase = !increase; } @@ -291,7 +290,7 @@ bool FCajunMaster::IsLeader (player_t *player) AActor *DBot::Choose_Mate () { int count; - fixed_t closest_dist, test; + double closest_dist, test; AActor *target; AActor *observer; @@ -312,7 +311,7 @@ AActor *DBot::Choose_Mate () last_mate = NULL; target = NULL; - closest_dist = FIXED_MAX; + closest_dist = FLT_MAX; if (bot_observer) observer = players[consoleplayer].mo; else @@ -334,7 +333,7 @@ AActor *DBot::Choose_Mate () { if (P_CheckSight (player->mo, client->mo, SF_IGNOREVISIBILITY)) { - test = client->mo->AproxDistance(player->mo); + test = client->mo->Distance2D(player->mo); if (test < closest_dist) { @@ -368,9 +367,9 @@ AActor *DBot::Choose_Mate () AActor *DBot::Find_enemy () { int count; - fixed_t closest_dist, temp; //To target. + double closest_dist, temp; //To target. AActor *target; - angle_t vangle; + DAngle vangle; AActor *observer; if (!deathmatch) @@ -380,13 +379,13 @@ AActor *DBot::Find_enemy () //Note: It's hard to ambush a bot who is not alone if (allround || mate) - vangle = ANGLE_MAX; + vangle = 360.; else vangle = ENEMY_SCAN_FOV; allround = false; target = NULL; - closest_dist = FIXED_MAX; + closest_dist = FLT_MAX; if (bot_observer) observer = players[consoleplayer].mo; else @@ -404,7 +403,7 @@ AActor *DBot::Find_enemy () if (Check_LOS (client->mo, vangle)) //Here's a strange one, when bot is standing still, the P_CheckSight within Check_LOS almost always returns false. tought it should be the same checksight as below but.. (below works) something must be fuckin wierd screded up. //if(P_CheckSight(player->mo, players[count].mo)) { - temp = client->mo->AproxDistance(player->mo); + temp = client->mo->Distance2D(player->mo); //Too dark? if (temp > DARK_DIST && @@ -463,7 +462,7 @@ void FCajunMaster::SetBodyAt (const DVector3 &pos, int hostnum) //Emulates missile travel. Returns distance travelled. -fixed_t FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd) +double FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd) { AActor *th = Spawn ("CajunTrace", source->PosPlusZ(4*8.), NO_REPLACE); @@ -472,23 +471,22 @@ fixed_t FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd) th->Vel = source->Vec3To(dest).Resized(th->Speed); - fixed_t dist = 0; + double dist = 0; while (dist < SAFE_SELF_MISDIST) { - dist += th->_f_speed(); - th->Move(th->_f_velx(), th->_f_vely(), th->_f_velz()); - if (!CleanAhead (th, th->_f_X(), th->_f_Y(), cmd)) + dist += th->Speed; + th->Move(th->Vel); + if (!CleanAhead (th, th->X(), th->Y(), cmd)) break; } th->Destroy (); return dist; } -angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) +DAngle DBot::FireRox (AActor *enemy, ticcmd_t *cmd) { double dist; - angle_t ang; AActor *actor; double m; @@ -497,8 +495,8 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) actor = bglobal.body2; dist = actor->Distance2D (enemy); - if (dist < SAFE_SELF_MISDIST/FRACUNIT) - return 0; + if (dist < SAFE_SELF_MISDIST) + return 0.; //Predict. m = ((dist+1) / GetDefaultByName("Rocket")->Speed); @@ -508,12 +506,11 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile { FCheckPosition tm; - if (bglobal.SafeCheckPosition (player->mo, actor->_f_X(), actor->_f_Y(), tm)) + if (bglobal.SafeCheckPosition (player->mo, actor->X(), actor->Y(), tm)) { if (bglobal.FakeFire (actor, bglobal.body1, cmd) >= SAFE_SELF_MISDIST) { - ang = actor->__f_AngleTo(bglobal.body1); - return ang; + return actor->AngleTo(bglobal.body1); } } } @@ -522,21 +519,20 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) { if (bglobal.FakeFire (player->mo, enemy, cmd) >= SAFE_SELF_MISDIST) { - ang = player->mo->__f_AngleTo(enemy); - return ang; + return player->mo->AngleTo(enemy); } } - return 0; + return 0.; } // [RH] We absolutely do not want to pick things up here. The bot code is // executed apart from all the other simulation code, so we don't want it // creating side-effects during gameplay. -bool FCajunMaster::SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm) +bool FCajunMaster::SafeCheckPosition (AActor *actor, double x, double y, FCheckPosition &tm) { ActorFlags savedFlags = actor->flags; actor->flags &= ~MF_PICKUP; - bool res = P_CheckPosition (actor, x, y, tm); + bool res = P_CheckPosition (actor, DVector2(x, y), tm); actor->flags = savedFlags; return res; } diff --git a/src/b_move.cpp b/src/b_move.cpp index a879ef3d2..643002968 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -35,21 +35,21 @@ extern dirtype_t diags[4]; //which can be a weapon/enemy/item whatever. void DBot::Roam (ticcmd_t *cmd) { - int delta; if (Reachable(dest)) { // Straight towards it. - angle = player->mo->__f_AngleTo(dest); + Angle = player->mo->AngleTo(dest); } else if (player->mo->movedir < 8) // turn towards movement direction if not there yet { - angle &= (angle_t)(7<<29); - delta = angle - (player->mo->movedir << 29); + // no point doing this with floating point angles... + unsigned angle = Angle.BAMs() & (unsigned)(7 << 29); + int delta = angle - (player->mo->movedir << 29); if (delta > 0) - angle -= ANG45; + Angle -= 45; else if (delta < 0) - angle += ANG45; + Angle += 45; } // chase towards destination. @@ -61,7 +61,7 @@ void DBot::Roam (ticcmd_t *cmd) bool DBot::Move (ticcmd_t *cmd) { - fixed_t tryx, tryy; + double tryx, tryy; bool try_ok; int good; @@ -71,8 +71,8 @@ bool DBot::Move (ticcmd_t *cmd) if ((unsigned)player->mo->movedir >= 8) I_Error ("Weird bot movedir!"); - tryx = player->mo->_f_X() + 8*xspeed[player->mo->movedir]; - tryy = player->mo->_f_Y() + 8*yspeed[player->mo->movedir]; + tryx = player->mo->X() + 8*xspeed[player->mo->movedir]; + tryy = player->mo->Y() + 8*yspeed[player->mo->movedir]; try_ok = bglobal.CleanAhead (player->mo, tryx, tryy, cmd); @@ -148,18 +148,18 @@ void DBot::NewChaseDir (ticcmd_t *cmd) olddir = (dirtype_t)player->mo->movedir; turnaround = opposite[olddir]; - fixedvec2 delta = player->mo->_f_Vec2To(dest); + DVector2 delta = player->mo->Vec2To(dest); - if (delta.x > 10*FRACUNIT) + if (delta.X > 10) d[1] = DI_EAST; - else if (delta.x < -10*FRACUNIT) + else if (delta.X < -10) d[1] = DI_WEST; else d[1] = DI_NODIR; - if (delta.y < -10*FRACUNIT) + if (delta.Y < -10) d[2] = DI_SOUTH; - else if (delta.y > 10*FRACUNIT) + else if (delta.Y > 10) d[2] = DI_NORTH; else d[2] = DI_NODIR; @@ -167,19 +167,19 @@ void DBot::NewChaseDir (ticcmd_t *cmd) // try direct route if (d[1] != DI_NODIR && d[2] != DI_NODIR) { - player->mo->movedir = diags[((delta.y<0)<<1)+(delta.x>0)]; + player->mo->movedir = diags[((delta.Y < 0) << 1) + (delta.X > 0)]; if (player->mo->movedir != turnaround && TryWalk(cmd)) return; } // try other directions - if (pr_botnewchasedir() > 200 - || abs(delta.y)>abs(delta.x)) - { - tdir=d[1]; - d[1]=d[2]; - d[2]=(dirtype_t)tdir; - } + if (pr_botnewchasedir() > 200 + || fabs(delta.Y) > fabs(delta.X)) + { + tdir = d[1]; + d[1] = d[2]; + d[2] = (dirtype_t)tdir; + } if (d[1]==turnaround) d[1]=DI_NODIR; @@ -260,7 +260,7 @@ void DBot::NewChaseDir (ticcmd_t *cmd) // This is also a traverse function for // bots pre-rocket fire (preventing suicide) // -bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cmd) +bool FCajunMaster::CleanAhead (AActor *thing, double x, double y, ticcmd_t *cmd) { FCheckPosition tm; @@ -272,14 +272,14 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm if (tm.ceilingz - tm.floorz < thing->Height) return false; // doesn't fit - double maxmove = FIXED2FLOAT(MAXMOVEHEIGHT); + double maxmove = MAXMOVEHEIGHT; if (!(thing->flags&MF_MISSILE)) { - if(tm.floorz > (thing->Sector->floorplane._f_ZatPointF(x, y)+maxmove)) //Too high wall + if(tm.floorz > (thing->Sector->floorplane.ZatPoint(x, y)+maxmove)) //Too high wall return false; //Jumpable - if(tm.floorz > (thing->Sector->floorplane._f_ZatPointF(x, y)+thing->MaxStepHeight)) + if(tm.floorz > (thing->Sector->floorplane.ZatPoint(x, y)+thing->MaxStepHeight)) cmd->ucmd.buttons |= BT_JUMP; @@ -289,7 +289,7 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm // jump out of water // if((thing->eflags & (MF_UNDERWATER|MF_TOUCHWATER))==(MF_UNDERWATER|MF_TOUCHWATER)) -// maxstep=37*FRACUNIT; +// maxstep=37; if ( !(thing->flags & MF_TELEPORT) && (tm.floorz - thing->Z() > thing->MaxStepHeight) ) @@ -327,11 +327,11 @@ void DBot::TurnToAng () if(enemy) if(!dest) //happens when running after item in combat situations, or normal, prevents weak turns if(player->ReadyWeapon->ProjectileType == NULL && !(player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON)) - if(Check_LOS(enemy, SHOOTFOV+5*ANGLE_1)) + if(Check_LOS(enemy, SHOOTFOV+5)) maxturn = 3; } - DAngle distance = deltaangle(player->mo->Angles.Yaw, ANGLE2DBL(angle)); + DAngle distance = deltaangle(player->mo->Angles.Yaw, Angle); if (fabs (distance) < OKAYRANGE && !enemy) return; @@ -348,8 +348,8 @@ void DBot::Pitch (AActor *target) double aim; double diff; - diff = target->_f_Z() - player->mo->_f_Z(); - aim = g_atan(diff / (double)player->mo->AproxDistance(target)); + diff = target->Z() - player->mo->Z(); + aim = g_atan(diff / player->mo->Distance2D(target)); player->mo->Angles.Pitch = ToDegrees(aim); } diff --git a/src/b_think.cpp b/src/b_think.cpp index dd6ce49aa..0ff75722a 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -75,38 +75,41 @@ void DBot::Think () } } +#define THINKDISTSQ (50000.*50000./(65536.*65536.)) //how the bot moves. //MAIN movement function. void DBot::ThinkForMove (ticcmd_t *cmd) { - fixed_t dist; + double dist; bool stuck; int r; stuck = false; - dist = dest ? player->mo->AproxDistance(dest) : 0; + dist = dest ? player->mo->Distance2D(dest) : 0; if (missile && - ((!missile->_f_velx() || !missile->_f_vely()) || !Check_LOS(missile, SHOOTFOV*3/2))) + (!missile->Vel.X || !missile->Vel.Y || !Check_LOS(missile, SHOOTFOV*3/2))) { sleft = !sleft; missile = NULL; //Probably ended its travel. } +#if 0 // this has always been broken and without any reference it cannot be fixed. if (player->mo->Angles.Pitch > 0) player->mo->Angles.Pitch -= 80; else if (player->mo->Angles.Pitch <= -60) player->mo->Angles.Pitch += 80; +#endif //HOW TO MOVE: - if (missile && (player->mo->AproxDistance(missile)mo->Distance2D(missile)mo->__f_AngleTo(missile); + Angle = player->mo->AngleTo(missile); cmd->ucmd.sidemove = sleft ? -SIDERUN : SIDERUN; cmd->ucmd.forwardmove = -FORWARDRUN; //Back IS best. - if ((player->mo->AproxDistance(oldx, oldy)<50000) + if ((player->mo->Pos() - old).LengthSquared() < THINKDISTSQ && t_strafe<=0) { t_strafe = 5; @@ -159,7 +162,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) t_fight = AFTERTICS; if (t_strafe <= 0 && - (player->mo->AproxDistance(oldx, oldy)<50000 + ((player->mo->Pos() - old).LengthSquared() < THINKDISTSQ || ((pr_botmove()%30)==10)) ) { @@ -168,7 +171,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) sleft = !sleft; } - angle = player->mo->__f_AngleTo(enemy); + Angle = player->mo->AngleTo(enemy); if (player->ReadyWeapon == NULL || player->mo->Distance2D(enemy) > @@ -196,7 +199,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) } else if (mate && !enemy && (!dest || dest==mate)) //Follow mate move. { - fixed_t matedist; + double matedist; Pitch (mate); @@ -209,9 +212,9 @@ void DBot::ThinkForMove (ticcmd_t *cmd) goto roam; } - angle = player->mo->__f_AngleTo(mate); + Angle = player->mo->AngleTo(mate); - matedist = player->mo->AproxDistance(mate); + matedist = player->mo->Distance2D(mate); if (matedist > (FRIEND_DIST*2)) cmd->ucmd.forwardmove = FORWARDRUN; else if (matedist > FRIEND_DIST) @@ -244,7 +247,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) (pr_botmove()%100)>skill.isp) && player->ReadyWeapon != NULL && !(player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)) dest = enemy;//Dont let enemy kill the bot by supressive fire. So charge enemy. else //hide while t_fight, but keep view at enemy. - angle = player->mo->__f_AngleTo(enemy); + Angle = player->mo->AngleTo(enemy); } //Just a monster, so kill it. else dest = enemy; @@ -306,8 +309,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) if (t_fight<(AFTERTICS/2)) player->mo->flags |= MF_DROPOFF; - oldx = player->mo->_f_X(); - oldy = player->mo->_f_Y(); + old = player->mo->Pos(); } //BOT_WhatToGet diff --git a/src/doomdef.h b/src/doomdef.h index 67c43787c..89d7ba673 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -350,7 +350,7 @@ enum { BCOMPATF_SETSLOPEOVERFLOW = 1 << 0, // SetSlope things can overflow BCOMPATF_RESETPLAYERSPEED = 1 << 1, // Set player speed to 1.0 when changing maps - BCOMPATF_VILEGHOSTS = 1 << 2, // Monsters' _f_radius() and height aren't restored properly when resurrected. + BCOMPATF_VILEGHOSTS = 1 << 2, // Monsters' radius and height aren't restored properly when resurrected. BCOMPATF_BADTELEPORTERS = 1 << 3, // Ignore tags on Teleport specials BCOMPATF_BADPORTALS = 1 << 4, // Restores the old unstable portal behavior BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 811d8748a..76aecea8c 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -99,8 +99,9 @@ dirtype_t diags[4] = DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST }; -fixed_t xspeed[8] = {FRACUNIT,46341,0,-46341,-FRACUNIT,-46341,0,46341}; -fixed_t yspeed[8] = {0,46341,FRACUNIT,46341,0,-46341,-FRACUNIT,-46341}; +#define SQRTHALF 0.7071075439453125 +double xspeed[8] = {1,SQRTHALF,0,-SQRTHALF,-1,-SQRTHALF,0,SQRTHALF}; +double yspeed[8] = {0,SQRTHALF,1,SQRTHALF,0,-SQRTHALF,-1,-SQRTHALF}; void P_RandomChaseDir (AActor *actor); @@ -511,8 +512,8 @@ bool P_Move (AActor *actor) } } - tryx = (origx = actor->_f_X()) + (deltax = FixedMul (speed, xspeed[actor->movedir])); - tryy = (origy = actor->_f_Y()) + (deltay = FixedMul (speed, yspeed[actor->movedir])); + tryx = (origx = actor->_f_X()) + (deltax = fixed_t (speed * xspeed[actor->movedir])); + tryy = (origy = actor->_f_Y()) + (deltay = fixed_t (speed * yspeed[actor->movedir])); // Like P_XYMovement this should do multiple moves if the step size is too large @@ -2599,8 +2600,8 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) { const fixed_t absSpeed = abs (self->_f_speed()); fixedvec2 viletry = self->Vec2Offset( - FixedMul (absSpeed, xspeed[self->movedir]), - FixedMul (absSpeed, yspeed[self->movedir]), true); + int (absSpeed * xspeed[self->movedir]), + int (absSpeed * yspeed[self->movedir]), true); FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); diff --git a/src/p_enemy.h b/src/p_enemy.h index 2912f847f..ee091ce25 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -24,7 +24,7 @@ enum dirtype_t NUMDIRS }; -extern fixed_t xspeed[8], yspeed[8]; +extern double xspeed[8], yspeed[8]; enum LO_Flags { diff --git a/src/p_local.h b/src/p_local.h index 367f54b3a..47be75835 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -281,10 +281,14 @@ inline bool P_CheckPosition(AActor *thing, const fixedvec3 &pos, bool actorsonly { return P_CheckPosition(thing, pos.x, pos.y, actorsonly); } -inline bool P_CheckPosition(AActor *thing, const DVector3 &pos, bool actorsonly = false) +inline bool P_CheckPosition(AActor *thing, const DVector2 &pos, bool actorsonly = false) { return P_CheckPosition(thing, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), actorsonly); } +inline bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, bool actorsonly = false) +{ + return P_CheckPosition(thing, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), tm, actorsonly); +} AActor *P_CheckOnmobj (AActor *thing); void P_FakeZMovement (AActor *mo); bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false); diff --git a/src/p_map.cpp b/src/p_map.cpp index 3a2b66500..247dda65f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2828,7 +2828,7 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t } // set openrange, opentop, openbottom - P_LineOpening(open, slidemo, li, it.InterceptPoint(in)); + P_LineOpening(open, slidemo, li, it._f_InterceptPoint(in)); if (open.range < slidemo->Height) goto isblocking; // doesn't fit @@ -3184,7 +3184,7 @@ bool FSlide::BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_ } - P_LineOpening(open, slidemo, li, it.InterceptPoint(in)); // set openrange, opentop, openbottom + P_LineOpening(open, slidemo, li, it._f_InterceptPoint(in)); // set openrange, opentop, openbottom if (open.range < slidemo->Height) goto bounceblocking; // doesn't fit @@ -3806,7 +3806,7 @@ struct aim_t // Crosses a two sided line. // A two sided line will restrict the possible target ranges. FLineOpening open; - P_LineOpening(open, NULL, li, it.InterceptPoint(in), FIXED_MIN, 0, FFCF_NODROPOFF); + P_LineOpening(open, NULL, li, it._f_InterceptPoint(in), FIXED_MIN, 0, FFCF_NODROPOFF); // The following code assumes that portals on the front of the line have already been processed. @@ -3831,7 +3831,7 @@ struct aim_t return; int planestocheck; - if (!AimTraverse3DFloors(it.Trace(), in, frontflag, &planestocheck)) + if (!AimTraverse3DFloors(it._f_Trace(), in, frontflag, &planestocheck)) return; if (aimdebug) @@ -3961,7 +3961,7 @@ struct aim_t fixed_t cosine = finecosine[thingpitch >> ANGLETOFINESHIFT]; if (cosine != 0) { - fixed_t d3 = FixedDiv(FixedMul(P_AproxDistance(it.Trace().dx, it.Trace().dy), in->frac), cosine); + fixed_t d3 = FixedDiv(FixedMul(P_AproxDistance(it._f_Trace().dx, it._f_Trace().dy), in->frac), cosine); if (d3 > attackrange) { return; @@ -4560,7 +4560,7 @@ void P_TraceBleed(int damage, AActor *target, angle_t angle, int pitch) void P_TraceBleed(int damage, AActor *target, AActor *missile) { - int pitch; + DAngle pitch; if (target == NULL || missile->flags3 & MF3_BLOODLESSIMPACT) { @@ -4572,15 +4572,13 @@ void P_TraceBleed(int damage, AActor *target, AActor *missile) double aim; aim = g_atan((double)missile->_f_velz() / (double)target->AproxDistance(missile)); - pitch = -(int)(aim * ANGLE_180 / PI); + pitch = -ToDegrees(aim); } else { - pitch = 0; + pitch = 0.; } - P_TraceBleed(damage, target->_f_X(), target->_f_Y(), target->_f_Z() + target->_f_height() / 2, - target, missile->__f_AngleTo(target), - pitch); + P_TraceBleed(damage, target->PosPlusZ(target->Height/2), target, missile->AngleTo(target), pitch); } //========================================================================== @@ -4958,7 +4956,7 @@ bool P_UseTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t end } else { - P_LineOpening(open, NULL, in->d.line, it.InterceptPoint(in)); + P_LineOpening(open, NULL, in->d.line, it._f_InterceptPoint(in)); } if (open.range <= 0 || (in->d.line->special != 0 && (i_compatflags & COMPATF_USEBLOCKING))) @@ -5066,7 +5064,7 @@ bool P_NoWayTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t e if (ld->special) continue; if (ld->isLinePortal()) return false; if (ld->flags&(ML_BLOCKING | ML_BLOCKEVERYTHING | ML_BLOCK_PLAYERS)) return true; - P_LineOpening(open, NULL, ld, it.InterceptPoint(in)); + P_LineOpening(open, NULL, ld, it._f_InterceptPoint(in)); if (open.range <= 0 || open.bottom > usething->Z() + usething->MaxStepHeight || open.top < usething->Top()) return true; @@ -5148,7 +5146,7 @@ bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType) { // Check line if (in->d.line->special != UsePuzzleItem) { - P_LineOpening(open, NULL, in->d.line, it.InterceptPoint(in)); + P_LineOpening(open, NULL, in->d.line, it._f_InterceptPoint(in)); if (open.range <= 0) { return false; // can't use through a wall diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 91b45a373..b4d6dc8fe 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -1425,6 +1425,7 @@ intercept_t *FPathTraverse::Next() { dist = scan->frac; in = scan; + in->Frac = FIXED2FLOAT(in->frac); } } @@ -1658,6 +1659,10 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl break; } } + ftrace.dx = FIXED2DBL(trace.dx); + ftrace.dy = FIXED2DBL(trace.dy); + ftrace.x = FIXED2DBL(trace.x); + ftrace.y = FIXED2DBL(trace.y); } //=========================================================================== diff --git a/src/p_maputl.h b/src/p_maputl.h index 727b56c2b..f2442d2bb 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -25,6 +25,7 @@ struct divline_t struct intercept_t { + double Frac; fixed_t frac; // along trace line bool isaline; bool done; @@ -390,6 +391,7 @@ class FPathTraverse protected: static TArray intercepts; + divline_t ftrace; fdivline_t trace; fixed_t startfrac; unsigned int intercept_index; @@ -407,12 +409,17 @@ public: { init(x1, y1, x2, y2, flags, startfrac); } + FPathTraverse(double x1, double y1, double x2, double y2, int flags, double startfrac = 0) + { + init(FLOAT2FIXED(x1), FLOAT2FIXED(y1), FLOAT2FIXED(x2), FLOAT2FIXED(y2), flags, FLOAT2FIXED(startfrac)); + } void init(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac = 0); int PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos = NULL); virtual ~FPathTraverse(); - const fdivline_t &Trace() const { return trace; } + const fdivline_t &_f_Trace() const { return trace; } + const divline_t &Trace() const { return ftrace; } - inline fixedvec2 InterceptPoint(const intercept_t *in) + inline fixedvec2 _f_InterceptPoint(const intercept_t *in) { return { @@ -420,6 +427,14 @@ public: trace.y + FixedMul(trace.dy, in->frac) }; } + inline DVector2 InterceptPoint(const intercept_t *in) + { + return + { + FIXED2DBL(trace.x + FixedMul(trace.dx, in->frac)), + FIXED2DBL(trace.y + FixedMul(trace.dy, in->frac)) + }; + } }; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index c10ff482d..b59ae30aa 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3171,9 +3171,8 @@ bool AActor::IsOkayToAttack (AActor *link) // to only allow the check to succeed if the enemy was in a ~84� FOV of the player if (flags3 & MF3_SCREENSEEKER) { - angle_t angle = Friend->__f_AngleTo(link) - Friend->_f_angle(); - angle >>= 24; - if (angle>226 || angle<30) + DAngle angle = absangle(Friend->AngleTo(link), Friend->Angles.Yaw); + if (angle < 30 * (256./360.)) { return true; } @@ -3562,7 +3561,7 @@ void AActor::Tick () { if (!players[i].Bot->missile && (flags3 & MF3_WARNBOT)) { //warn for incoming missiles. - if (target != players[i].mo && players[i].Bot->Check_LOS (this, ANGLE_90)) + if (target != players[i].mo && players[i].Bot->Check_LOS (this, 90.)) players[i].Bot->missile = this; } } diff --git a/src/p_user.cpp b/src/p_user.cpp index 8783bac99..c81fe10af 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -3183,37 +3183,6 @@ void player_t::Serialize (FArchive &arc) onground = (mo->Z() <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (cheats & CF_NOCLIP2); } - if (SaveVersion < 4514 && IsBot) - { - Bot = new DBot; - - arc << Bot->angle - << Bot->dest - << Bot->prev - << Bot->enemy - << Bot->missile - << Bot->mate - << Bot->last_mate - << Bot->skill - << Bot->t_active - << Bot->t_respawn - << Bot->t_strafe - << Bot->t_react - << Bot->t_fight - << Bot->t_roam - << Bot->t_rocket - << Bot->first_shot - << Bot->sleft - << Bot->allround - << Bot->oldx - << Bot->oldy; - } - - if (SaveVersion < 4516 && Bot != NULL) - { - Bot->player = this; - } - if (arc.IsLoading ()) { // If the player reloaded because they pressed +use after dying, we diff --git a/src/portal.cpp b/src/portal.cpp index 1d7419b66..81a8e4467 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -716,7 +716,7 @@ fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy) // Teleport portals are intentionally ignored since skipping this stuff is their entire reason for existence. if (port->mFlags & PORTF_INTERACTIVE) { - fixedvec2 hit = it.InterceptPoint(in); + fixedvec2 hit = it._f_InterceptPoint(in); if (port->mType == PORTT_LINKED) {