- floatification of bot code.

This commit is contained in:
Christoph Oelckers 2016-03-26 00:34:56 +01:00
parent 8e13d13916
commit e42b0171b3
17 changed files with 198 additions and 232 deletions

View file

@ -828,16 +828,6 @@ public:
return P_AproxDistance(_f_X() - otherx, _f_Y() - othery); 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 // 'absolute' is reserved for a linked portal implementation which needs
// to distinguish between portal-aware and portal-unaware distance calculation. // to distinguish between portal-aware and portal-unaware distance calculation.
fixed_t AproxDistance(AActor *other, bool absolute = false) fixed_t AproxDistance(AActor *other, bool absolute = false)
@ -846,13 +836,14 @@ public:
return P_AproxDistance(_f_X() - otherpos.x, _f_Y() - otherpos.y); 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) fixed_t AproxDistance(AActor *other, fixed_t xadd, fixed_t yadd, bool absolute = false)
{ {
fixedvec3 otherpos = absolute ? other->_f_Pos() : other->_f_PosRelative(this); fixedvec3 otherpos = absolute ? other->_f_Pos() : other->_f_PosRelative(this);
return P_AproxDistance(_f_X() - otherpos.x + xadd, _f_Y() - otherpos.y + yadd); 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) double Distance2D(AActor *other, bool absolute = false)
{ {
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
@ -864,6 +855,13 @@ public:
return DVector2(X() - x, Y() - y).Length(); 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 // a full 3D version of the above
double Distance3D(AActor *other, bool absolute = false) double Distance3D(AActor *other, bool absolute = false)
{ {
@ -871,17 +869,6 @@ public:
return (Pos() - otherpos).Length(); 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) DAngle AngleTo(AActor *other, bool absolute = false)
{ {
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
@ -1064,6 +1051,10 @@ public:
SetOrigin(npos.x, npos.y, npos.z, moving); 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) void SetOrigin(double x, double y, double z, bool moving)
{ {
SetOrigin(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(z), moving); SetOrigin(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(z), moving);

View file

@ -815,7 +815,7 @@ CVAR(Bool, am_portaloverlay, true, CVAR_ARCHIVE)
CCMD(am_togglefollow) CCMD(am_togglefollow)
{ {
am_followplayer = !am_followplayer; am_followplayer = !am_followplayer;
f_oldloc.x = FIXED_MAX; f_oldloc.x = FLT_MAX;
Printf ("%s\n", GStrings(am_followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF")); Printf ("%s\n", GStrings(am_followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF"));
} }
@ -1022,7 +1022,7 @@ bool AM_addMark ()
static void AM_findMinMaxBoundaries () static void AM_findMinMaxBoundaries ()
{ {
min_x = min_y = FIXED_MAX; min_x = min_y = FLT_MAX;
max_x = max_y = FIXED_MIN; max_x = max_y = FIXED_MIN;
for (int i = 0; i < numvertexes; i++) 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[2] = max_x; ys[2] = max_y;
xs[3] = min_x; ys[3] = max_y; xs[3] = min_x; ys[3] = max_y;
xs[4] = m_x + m_w/2; ys[4] = m_y + m_h/2; 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; rmax_x = rmax_y = FIXED_MIN;
for (i = 0; i < 5; ++i) for (i = 0; i < 5; ++i)
@ -1175,7 +1175,7 @@ void AM_changeWindowLoc ()
if (m_paninc.x || m_paninc.y) if (m_paninc.x || m_paninc.y)
{ {
am_followplayer = false; am_followplayer = false;
f_oldloc.x = FIXED_MAX; f_oldloc.x = FLT_MAX;
} }
double oldmx = m_x, oldmy = m_y; double oldmx = m_x, oldmy = m_y;
@ -1220,7 +1220,7 @@ void AM_initVariables ()
Button_AM_ZoomOut.Reset(); Button_AM_ZoomOut.Reset();
f_oldloc.x = FIXED_MAX; f_oldloc.x = FLT_MAX;
amclock = 0; amclock = 0;
m_paninc.x = m_paninc.y = 0; m_paninc.x = m_paninc.y = 0;

View file

@ -33,7 +33,7 @@ DBot::DBot ()
void DBot::Clear () void DBot::Clear ()
{ {
player = NULL; player = NULL;
angle = 0; Angle = 0.;
dest = NULL; dest = NULL;
prev = NULL; prev = NULL;
enemy = NULL; enemy = NULL;
@ -52,27 +52,15 @@ void DBot::Clear ()
sleft = false; sleft = false;
allround = false; allround = false;
increase = false; increase = false;
oldx = 0; old = { 0, 0 };
oldy = 0;
} }
void DBot::Serialize (FArchive &arc) void DBot::Serialize (FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize (arc);
if (SaveVersion < 4515) arc << player
{ << Angle
angle_t savedyaw;
int savedpitch;
arc << savedyaw
<< savedpitch;
}
else
{
arc << player;
}
arc << angle
<< dest << dest
<< prev << prev
<< enemy << enemy
@ -91,8 +79,7 @@ void DBot::Serialize (FArchive &arc)
<< sleft << sleft
<< allround << allround
<< increase << increase
<< oldx << old;
<< oldy;
} }
void DBot::Tick () void DBot::Tick ()

View file

@ -31,18 +31,18 @@
#define BOTFILENAME "bots.cfg" #define BOTFILENAME "bots.cfg"
#define MAX_TRAVERSE_DIST 100000000 //10 meters, used within b_func.c #define MAX_TRAVERSE_DIST (100000000/65536.) //10 meters, used within b_func.c
#define AVOID_DIST 45000000 //Try avoid incoming missiles once they reached this close #define AVOID_DIST (45000000/65536.) //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 SAFE_SELF_MISDIST (140.) //Distance from self to target where it's safe to pull a rocket.
#define FRIEND_DIST 15000000 //To friend. #define FRIEND_DIST (15000000/65536.) //To friend.
#define DARK_DIST 5000000 //Distance that bot can see enemies in the dark from. #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 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 MAX_MONSTER_TARGET_DIST (50000000/65536.) //Too high can slow down the performance, see P_mobj.c
#define ENEMY_SCAN_FOV (120*ANGLE_1) #define ENEMY_SCAN_FOV (120.)
#define THINGTRYTICK 1000 #define THINGTRYTICK 1000
#define MAXMOVEHEIGHT (32*FRACUNIT) //MAXSTEPMOVE but with jumping counted in. #define MAXMOVEHEIGHT (32) //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 GETINCOMBAT (35000000/65536.) //Max distance to item. if it's due to be icked up in a combat situation.
#define SHOOTFOV (60*ANGLE_1) #define SHOOTFOV (60.)
#define AFTERTICS (2*TICRATE) //Seconds that bot will be alert on an recent enemy. Ie not looking the other way #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. #define MAXROAM (4*TICRATE) //When this time is elapsed the bot will roam after something else.
//monster mod //monster mod
@ -104,11 +104,11 @@ public:
void FinishTravel (); void FinishTravel ();
bool IsLeader (player_t *player); bool IsLeader (player_t *player);
void SetBodyAt (const DVector3 &pos, int hostnum); void SetBodyAt (const DVector3 &pos, int hostnum);
fixed_t FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd); double FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd);
bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm); bool SafeCheckPosition (AActor *actor, double x, double y, FCheckPosition &tm);
//(b_move.cpp) //(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); bool IsDangerous (sector_t *sec);
TArray<FString> getspawned; //Array of bots (their names) which should be spawned when starting a game. TArray<FString> getspawned; //Array of bots (their names) which should be spawned when starting a game.
@ -149,10 +149,10 @@ public:
void WhatToGet (AActor *item); void WhatToGet (AActor *item);
//(b_func.cpp) //(b_func.cpp)
bool Check_LOS (AActor *to, angle_t vangle); bool Check_LOS (AActor *to, DAngle vangle);
player_t *player; 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) // (used to get a smooth view movement)
TObjPtr<AActor> dest; // Move Destination. TObjPtr<AActor> dest; // Move Destination.
TObjPtr<AActor> prev; // Previous move destination. TObjPtr<AActor> prev; // Previous move destination.
@ -183,8 +183,7 @@ public:
bool allround; bool allround;
bool increase; bool increase;
fixed_t oldx; DVector2 old;
fixed_t oldy;
private: private:
//(b_think.cpp) //(b_think.cpp)
@ -197,7 +196,7 @@ private:
void Dofire (ticcmd_t *cmd); void Dofire (ticcmd_t *cmd);
AActor *Choose_Mate (); AActor *Choose_Mate ();
AActor *Find_enemy (); AActor *Find_enemy ();
angle_t FireRox (AActor *enemy, ticcmd_t *cmd); DAngle FireRox (AActor *enemy, ticcmd_t *cmd);
//(b_move.cpp) //(b_move.cpp)
void Roam (ticcmd_t *cmd); void Roam (ticcmd_t *cmd);

View file

@ -34,32 +34,32 @@ bool DBot::Reachable (AActor *rtarget)
if (player->mo == rtarget) if (player->mo == rtarget)
return false; return false;
if ((rtarget->Sector->ceilingplane.ZatPoint (rtarget) - if ((rtarget->Sector->ceilingplane.ZatPointF (rtarget) -
rtarget->Sector->floorplane.ZatPoint (rtarget)) rtarget->Sector->floorplane.ZatPointF (rtarget))
< player->mo->_f_height()) //Where rtarget is, player->mo can't be. < player->mo->Height) //Where rtarget is, player->mo can't be.
return false; return false;
sector_t *last_s = player->mo->Sector; sector_t *last_s = player->mo->Sector;
fixed_t last_z = last_s->floorplane.ZatPoint (player->mo); double last_z = last_s->floorplane.ZatPointF (player->mo);
fixed_t estimated_dist = player->mo->AproxDistance(rtarget); double estimated_dist = player->mo->Distance2D(rtarget);
bool reachable = true; 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; intercept_t *in;
while ((in = it.Next())) while ((in = it.Next()))
{ {
fixed_t hitx, hity; double hitx, hity;
fixed_t frac; double frac;
line_t *line; line_t *line;
AActor *thing; AActor *thing;
fixed_t dist; double dist;
sector_t *s; sector_t *s;
frac = in->frac - FixedDiv (4*FRACUNIT, MAX_TRAVERSE_DIST); frac = in->Frac - 4 /MAX_TRAVERSE_DIST;
dist = FixedMul (frac, MAX_TRAVERSE_DIST); dist = frac * MAX_TRAVERSE_DIST;
hitx = it.Trace().x + FixedMul (player->mo->_f_velx(), frac); hitx = it.Trace().x + player->mo->Vel.X * frac;
hity = it.Trace().y + FixedMul (player->mo->_f_vely(), frac); hity = it.Trace().y + player->mo->Vel.Y * frac;
if (in->isaline) if (in->isaline)
{ {
@ -73,13 +73,13 @@ bool DBot::Reachable (AActor *rtarget)
{ {
//Determine if going to use backsector/frontsector. //Determine if going to use backsector/frontsector.
s = (line->backsector == last_s) ? line->frontsector : line->backsector; s = (line->backsector == last_s) ? line->frontsector : line->backsector;
fixed_t ceilingheight = s->ceilingplane.ZatPoint (hitx, hity); double ceilingheight = s->ceilingplane.ZatPoint (hitx, hity);
fixed_t floorheight = s->floorplane.ZatPoint (hitx, hity); double floorheight = s->floorplane.ZatPoint (hitx, hity);
if (!bglobal.IsDangerous (s) && //Any nukage/lava? if (!bglobal.IsDangerous (s) && //Any nukage/lava?
(floorheight <= (last_z+MAXMOVEHEIGHT) (floorheight <= (last_z+MAXMOVEHEIGHT)
&& ((ceilingheight == floorheight && line->special) && ((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_z = floorheight;
last_s = s; last_s = s;
@ -100,7 +100,7 @@ bool DBot::Reachable (AActor *rtarget)
thing = in->d.thing; thing = in->d.thing;
if (thing == player->mo) //Can't reach self in this case. if (thing == player->mo) //Can't reach self in this case.
continue; 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; return true;
} }
@ -118,16 +118,16 @@ bool DBot::Reachable (AActor *rtarget)
//if these conditions are true, the function returns true. //if these conditions are true, the function returns true.
//GOOD TO KNOW is that the player's view angle //GOOD TO KNOW is that the player's view angle
//in doom is 90 degrees infront. //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)) if (!P_CheckSight (player->mo, to, SF_SEEPASTBLOCKEVERYTHING))
return false; // out of sight return false; // out of sight
if (vangle == ANGLE_MAX) if (vangle >= 360.)
return true; return true;
if (vangle == 0) if (vangle == 0)
return false; //Looker seems to be blind. 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. 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_penalty=0; //For shooting at shading target, if screen is red, MAKEME: When screen red.
int aiming_value; //The final aiming value. int aiming_value; //The final aiming value.
fixed_t dist; double Dist;
double fdist; DAngle an;
angle_t an; DAngle m;
int m;
double fm; double fm;
if (!enemy || !(enemy->flags & MF_SHOOTABLE) || enemy->health <= 0) if (!enemy || !(enemy->flags & MF_SHOOTABLE) || enemy->health <= 0)
@ -172,7 +171,7 @@ void DBot::Dofire (ticcmd_t *cmd)
no_fire = true; no_fire = true;
//Distance to enemy. //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. //FIRE EACH TYPE OF WEAPON DIFFERENT: Here should all the different weapons go.
if (player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON) if (player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON)
@ -194,7 +193,7 @@ void DBot::Dofire (ticcmd_t *cmd)
else else
{ {
//*4 is for atmosphere, the chainsaws sounding and all.. //*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) else if (player->ReadyWeapon->WeaponFlags & WIF_BOT_BFG)
@ -210,11 +209,11 @@ void DBot::Dofire (ticcmd_t *cmd)
{ {
//Special rules for RL //Special rules for RL
an = FireRox (enemy, cmd); an = FireRox (enemy, cmd);
if(an) if(an != 0)
{ {
angle = an; Angle = an;
//have to be somewhat precise. to avoid suicide. //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; t_rocket = 9;
no_fire = false; no_fire = false;
@ -223,17 +222,17 @@ void DBot::Dofire (ticcmd_t *cmd)
} }
// prediction aiming // prediction aiming
shootmissile: shootmissile:
fdist = player->mo->Distance2D(enemy); Dist = player->mo->Distance2D(enemy);
fm = fdist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed; fm = Dist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed;
bglobal.SetBodyAt(enemy->Pos() + enemy->Vel.XY() * fm * 2, 1); 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)) if (Check_LOS (enemy, SHOOTFOV))
no_fire = false; no_fire = false;
} }
else else
{ {
//Other weapons, mostly instant hit stuff. //Other weapons, mostly instant hit stuff.
angle = player->mo->__f_AngleTo(enemy); Angle = player->mo->AngleTo(enemy);
aiming_penalty = 0; aiming_penalty = 0;
if (enemy->flags & MF_SHADOW) if (enemy->flags & MF_SHADOW)
aiming_penalty += (pr_botdofire()%25)+10; aiming_penalty += (pr_botdofire()%25)+10;
@ -246,17 +245,17 @@ shootmissile:
aiming_value = 1; aiming_value = 1;
m = ((SHOOTFOV/2)-(aiming_value*SHOOTFOV/200)); //Higher skill is more accurate m = ((SHOOTFOV/2)-(aiming_value*SHOOTFOV/200)); //Higher skill is more accurate
if (m <= 0) if (m <= 0)
m = 1; //Prevents lock. m = 1.; //Prevents lock.
if (m) if (m != 0)
{ {
if (increase) if (increase)
angle += m; Angle += m;
else 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; increase = !increase;
} }
@ -291,7 +290,7 @@ bool FCajunMaster::IsLeader (player_t *player)
AActor *DBot::Choose_Mate () AActor *DBot::Choose_Mate ()
{ {
int count; int count;
fixed_t closest_dist, test; double closest_dist, test;
AActor *target; AActor *target;
AActor *observer; AActor *observer;
@ -312,7 +311,7 @@ AActor *DBot::Choose_Mate ()
last_mate = NULL; last_mate = NULL;
target = NULL; target = NULL;
closest_dist = FIXED_MAX; closest_dist = FLT_MAX;
if (bot_observer) if (bot_observer)
observer = players[consoleplayer].mo; observer = players[consoleplayer].mo;
else else
@ -334,7 +333,7 @@ AActor *DBot::Choose_Mate ()
{ {
if (P_CheckSight (player->mo, client->mo, SF_IGNOREVISIBILITY)) 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) if (test < closest_dist)
{ {
@ -368,9 +367,9 @@ AActor *DBot::Choose_Mate ()
AActor *DBot::Find_enemy () AActor *DBot::Find_enemy ()
{ {
int count; int count;
fixed_t closest_dist, temp; //To target. double closest_dist, temp; //To target.
AActor *target; AActor *target;
angle_t vangle; DAngle vangle;
AActor *observer; AActor *observer;
if (!deathmatch) if (!deathmatch)
@ -380,13 +379,13 @@ AActor *DBot::Find_enemy ()
//Note: It's hard to ambush a bot who is not alone //Note: It's hard to ambush a bot who is not alone
if (allround || mate) if (allround || mate)
vangle = ANGLE_MAX; vangle = 360.;
else else
vangle = ENEMY_SCAN_FOV; vangle = ENEMY_SCAN_FOV;
allround = false; allround = false;
target = NULL; target = NULL;
closest_dist = FIXED_MAX; closest_dist = FLT_MAX;
if (bot_observer) if (bot_observer)
observer = players[consoleplayer].mo; observer = players[consoleplayer].mo;
else 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 (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)) //if(P_CheckSight(player->mo, players[count].mo))
{ {
temp = client->mo->AproxDistance(player->mo); temp = client->mo->Distance2D(player->mo);
//Too dark? //Too dark?
if (temp > DARK_DIST && if (temp > DARK_DIST &&
@ -463,7 +462,7 @@ void FCajunMaster::SetBodyAt (const DVector3 &pos, int hostnum)
//Emulates missile travel. Returns distance travelled. //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); 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); th->Vel = source->Vec3To(dest).Resized(th->Speed);
fixed_t dist = 0; double dist = 0;
while (dist < SAFE_SELF_MISDIST) while (dist < SAFE_SELF_MISDIST)
{ {
dist += th->_f_speed(); dist += th->Speed;
th->Move(th->_f_velx(), th->_f_vely(), th->_f_velz()); th->Move(th->Vel);
if (!CleanAhead (th, th->_f_X(), th->_f_Y(), cmd)) if (!CleanAhead (th, th->X(), th->Y(), cmd))
break; break;
} }
th->Destroy (); th->Destroy ();
return dist; return dist;
} }
angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) DAngle DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
{ {
double dist; double dist;
angle_t ang;
AActor *actor; AActor *actor;
double m; double m;
@ -497,8 +495,8 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
actor = bglobal.body2; actor = bglobal.body2;
dist = actor->Distance2D (enemy); dist = actor->Distance2D (enemy);
if (dist < SAFE_SELF_MISDIST/FRACUNIT) if (dist < SAFE_SELF_MISDIST)
return 0; return 0.;
//Predict. //Predict.
m = ((dist+1) / GetDefaultByName("Rocket")->Speed); 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 if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile
{ {
FCheckPosition tm; 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) if (bglobal.FakeFire (actor, bglobal.body1, cmd) >= SAFE_SELF_MISDIST)
{ {
ang = actor->__f_AngleTo(bglobal.body1); return actor->AngleTo(bglobal.body1);
return ang;
} }
} }
} }
@ -522,21 +519,20 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
{ {
if (bglobal.FakeFire (player->mo, enemy, cmd) >= SAFE_SELF_MISDIST) if (bglobal.FakeFire (player->mo, enemy, cmd) >= SAFE_SELF_MISDIST)
{ {
ang = player->mo->__f_AngleTo(enemy); return player->mo->AngleTo(enemy);
return ang;
} }
} }
return 0; return 0.;
} }
// [RH] We absolutely do not want to pick things up here. The bot code is // [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 // executed apart from all the other simulation code, so we don't want it
// creating side-effects during gameplay. // 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; ActorFlags savedFlags = actor->flags;
actor->flags &= ~MF_PICKUP; actor->flags &= ~MF_PICKUP;
bool res = P_CheckPosition (actor, x, y, tm); bool res = P_CheckPosition (actor, DVector2(x, y), tm);
actor->flags = savedFlags; actor->flags = savedFlags;
return res; return res;
} }

View file

@ -35,21 +35,21 @@ extern dirtype_t diags[4];
//which can be a weapon/enemy/item whatever. //which can be a weapon/enemy/item whatever.
void DBot::Roam (ticcmd_t *cmd) void DBot::Roam (ticcmd_t *cmd)
{ {
int delta;
if (Reachable(dest)) if (Reachable(dest))
{ // Straight towards it. { // 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 else if (player->mo->movedir < 8) // turn towards movement direction if not there yet
{ {
angle &= (angle_t)(7<<29); // no point doing this with floating point angles...
delta = angle - (player->mo->movedir << 29); unsigned angle = Angle.BAMs() & (unsigned)(7 << 29);
int delta = angle - (player->mo->movedir << 29);
if (delta > 0) if (delta > 0)
angle -= ANG45; Angle -= 45;
else if (delta < 0) else if (delta < 0)
angle += ANG45; Angle += 45;
} }
// chase towards destination. // chase towards destination.
@ -61,7 +61,7 @@ void DBot::Roam (ticcmd_t *cmd)
bool DBot::Move (ticcmd_t *cmd) bool DBot::Move (ticcmd_t *cmd)
{ {
fixed_t tryx, tryy; double tryx, tryy;
bool try_ok; bool try_ok;
int good; int good;
@ -71,8 +71,8 @@ bool DBot::Move (ticcmd_t *cmd)
if ((unsigned)player->mo->movedir >= 8) if ((unsigned)player->mo->movedir >= 8)
I_Error ("Weird bot movedir!"); I_Error ("Weird bot movedir!");
tryx = player->mo->_f_X() + 8*xspeed[player->mo->movedir]; tryx = player->mo->X() + 8*xspeed[player->mo->movedir];
tryy = player->mo->_f_Y() + 8*yspeed[player->mo->movedir]; tryy = player->mo->Y() + 8*yspeed[player->mo->movedir];
try_ok = bglobal.CleanAhead (player->mo, tryx, tryy, cmd); 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; olddir = (dirtype_t)player->mo->movedir;
turnaround = opposite[olddir]; 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; d[1] = DI_EAST;
else if (delta.x < -10*FRACUNIT) else if (delta.X < -10)
d[1] = DI_WEST; d[1] = DI_WEST;
else else
d[1] = DI_NODIR; d[1] = DI_NODIR;
if (delta.y < -10*FRACUNIT) if (delta.Y < -10)
d[2] = DI_SOUTH; d[2] = DI_SOUTH;
else if (delta.y > 10*FRACUNIT) else if (delta.Y > 10)
d[2] = DI_NORTH; d[2] = DI_NORTH;
else else
d[2] = DI_NODIR; d[2] = DI_NODIR;
@ -167,19 +167,19 @@ void DBot::NewChaseDir (ticcmd_t *cmd)
// try direct route // try direct route
if (d[1] != DI_NODIR && d[2] != DI_NODIR) 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)) if (player->mo->movedir != turnaround && TryWalk(cmd))
return; return;
} }
// try other directions // try other directions
if (pr_botnewchasedir() > 200 if (pr_botnewchasedir() > 200
|| abs(delta.y)>abs(delta.x)) || fabs(delta.Y) > fabs(delta.X))
{ {
tdir=d[1]; tdir = d[1];
d[1]=d[2]; d[1] = d[2];
d[2]=(dirtype_t)tdir; d[2] = (dirtype_t)tdir;
} }
if (d[1]==turnaround) if (d[1]==turnaround)
d[1]=DI_NODIR; d[1]=DI_NODIR;
@ -260,7 +260,7 @@ void DBot::NewChaseDir (ticcmd_t *cmd)
// This is also a traverse function for // This is also a traverse function for
// bots pre-rocket fire (preventing suicide) // 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; 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) if (tm.ceilingz - tm.floorz < thing->Height)
return false; // doesn't fit return false; // doesn't fit
double maxmove = FIXED2FLOAT(MAXMOVEHEIGHT); double maxmove = MAXMOVEHEIGHT;
if (!(thing->flags&MF_MISSILE)) 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; return false;
//Jumpable //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; 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 // jump out of water
// if((thing->eflags & (MF_UNDERWATER|MF_TOUCHWATER))==(MF_UNDERWATER|MF_TOUCHWATER)) // if((thing->eflags & (MF_UNDERWATER|MF_TOUCHWATER))==(MF_UNDERWATER|MF_TOUCHWATER))
// maxstep=37*FRACUNIT; // maxstep=37;
if ( !(thing->flags & MF_TELEPORT) && if ( !(thing->flags & MF_TELEPORT) &&
(tm.floorz - thing->Z() > thing->MaxStepHeight) ) (tm.floorz - thing->Z() > thing->MaxStepHeight) )
@ -327,11 +327,11 @@ void DBot::TurnToAng ()
if(enemy) if(enemy)
if(!dest) //happens when running after item in combat situations, or normal, prevents weak turns 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(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; maxturn = 3;
} }
DAngle distance = deltaangle(player->mo->Angles.Yaw, ANGLE2DBL(angle)); DAngle distance = deltaangle(player->mo->Angles.Yaw, Angle);
if (fabs (distance) < OKAYRANGE && !enemy) if (fabs (distance) < OKAYRANGE && !enemy)
return; return;
@ -348,8 +348,8 @@ void DBot::Pitch (AActor *target)
double aim; double aim;
double diff; double diff;
diff = target->_f_Z() - player->mo->_f_Z(); diff = target->Z() - player->mo->Z();
aim = g_atan(diff / (double)player->mo->AproxDistance(target)); aim = g_atan(diff / player->mo->Distance2D(target));
player->mo->Angles.Pitch = ToDegrees(aim); player->mo->Angles.Pitch = ToDegrees(aim);
} }

View file

@ -75,38 +75,41 @@ void DBot::Think ()
} }
} }
#define THINKDISTSQ (50000.*50000./(65536.*65536.))
//how the bot moves. //how the bot moves.
//MAIN movement function. //MAIN movement function.
void DBot::ThinkForMove (ticcmd_t *cmd) void DBot::ThinkForMove (ticcmd_t *cmd)
{ {
fixed_t dist; double dist;
bool stuck; bool stuck;
int r; int r;
stuck = false; stuck = false;
dist = dest ? player->mo->AproxDistance(dest) : 0; dist = dest ? player->mo->Distance2D(dest) : 0;
if (missile && 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; sleft = !sleft;
missile = NULL; //Probably ended its travel. 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) if (player->mo->Angles.Pitch > 0)
player->mo->Angles.Pitch -= 80; player->mo->Angles.Pitch -= 80;
else if (player->mo->Angles.Pitch <= -60) else if (player->mo->Angles.Pitch <= -60)
player->mo->Angles.Pitch += 80; player->mo->Angles.Pitch += 80;
#endif
//HOW TO MOVE: //HOW TO MOVE:
if (missile && (player->mo->AproxDistance(missile)<AVOID_DIST)) //try avoid missile got from P_Mobj.c thinking part. if (missile && (player->mo->Distance2D(missile)<AVOID_DIST)) //try avoid missile got from P_Mobj.c thinking part.
{ {
Pitch (missile); Pitch (missile);
angle = player->mo->__f_AngleTo(missile); Angle = player->mo->AngleTo(missile);
cmd->ucmd.sidemove = sleft ? -SIDERUN : SIDERUN; cmd->ucmd.sidemove = sleft ? -SIDERUN : SIDERUN;
cmd->ucmd.forwardmove = -FORWARDRUN; //Back IS best. 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<=0)
{ {
t_strafe = 5; t_strafe = 5;
@ -159,7 +162,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
t_fight = AFTERTICS; t_fight = AFTERTICS;
if (t_strafe <= 0 && if (t_strafe <= 0 &&
(player->mo->AproxDistance(oldx, oldy)<50000 ((player->mo->Pos() - old).LengthSquared() < THINKDISTSQ
|| ((pr_botmove()%30)==10)) || ((pr_botmove()%30)==10))
) )
{ {
@ -168,7 +171,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
sleft = !sleft; sleft = !sleft;
} }
angle = player->mo->__f_AngleTo(enemy); Angle = player->mo->AngleTo(enemy);
if (player->ReadyWeapon == NULL || if (player->ReadyWeapon == NULL ||
player->mo->Distance2D(enemy) > player->mo->Distance2D(enemy) >
@ -196,7 +199,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
} }
else if (mate && !enemy && (!dest || dest==mate)) //Follow mate move. else if (mate && !enemy && (!dest || dest==mate)) //Follow mate move.
{ {
fixed_t matedist; double matedist;
Pitch (mate); Pitch (mate);
@ -209,9 +212,9 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
goto roam; 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)) if (matedist > (FRIEND_DIST*2))
cmd->ucmd.forwardmove = FORWARDRUN; cmd->ucmd.forwardmove = FORWARDRUN;
else if (matedist > FRIEND_DIST) 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)) (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. dest = enemy;//Dont let enemy kill the bot by supressive fire. So charge enemy.
else //hide while t_fight, but keep view at 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. } //Just a monster, so kill it.
else else
dest = enemy; dest = enemy;
@ -306,8 +309,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
if (t_fight<(AFTERTICS/2)) if (t_fight<(AFTERTICS/2))
player->mo->flags |= MF_DROPOFF; player->mo->flags |= MF_DROPOFF;
oldx = player->mo->_f_X(); old = player->mo->Pos();
oldy = player->mo->_f_Y();
} }
//BOT_WhatToGet //BOT_WhatToGet

View file

@ -350,7 +350,7 @@ enum
{ {
BCOMPATF_SETSLOPEOVERFLOW = 1 << 0, // SetSlope things can overflow BCOMPATF_SETSLOPEOVERFLOW = 1 << 0, // SetSlope things can overflow
BCOMPATF_RESETPLAYERSPEED = 1 << 1, // Set player speed to 1.0 when changing maps 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_BADTELEPORTERS = 1 << 3, // Ignore tags on Teleport specials
BCOMPATF_BADPORTALS = 1 << 4, // Restores the old unstable portal behavior BCOMPATF_BADPORTALS = 1 << 4, // Restores the old unstable portal behavior
BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild

View file

@ -99,8 +99,9 @@ dirtype_t diags[4] =
DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST
}; };
fixed_t xspeed[8] = {FRACUNIT,46341,0,-46341,-FRACUNIT,-46341,0,46341}; #define SQRTHALF 0.7071075439453125
fixed_t yspeed[8] = {0,46341,FRACUNIT,46341,0,-46341,-FRACUNIT,-46341}; 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); 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])); tryx = (origx = actor->_f_X()) + (deltax = fixed_t (speed * xspeed[actor->movedir]));
tryy = (origy = actor->_f_Y()) + (deltay = FixedMul (speed, yspeed[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 // 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()); const fixed_t absSpeed = abs (self->_f_speed());
fixedvec2 viletry = self->Vec2Offset( fixedvec2 viletry = self->Vec2Offset(
FixedMul (absSpeed, xspeed[self->movedir]), int (absSpeed * xspeed[self->movedir]),
FixedMul (absSpeed, yspeed[self->movedir]), true); int (absSpeed * yspeed[self->movedir]), true);
FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); FPortalGroupArray check(FPortalGroupArray::PGA_Full3d);

View file

@ -24,7 +24,7 @@ enum dirtype_t
NUMDIRS NUMDIRS
}; };
extern fixed_t xspeed[8], yspeed[8]; extern double xspeed[8], yspeed[8];
enum LO_Flags enum LO_Flags
{ {

View file

@ -281,10 +281,14 @@ inline bool P_CheckPosition(AActor *thing, const fixedvec3 &pos, bool actorsonly
{ {
return P_CheckPosition(thing, pos.x, pos.y, 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); 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); AActor *P_CheckOnmobj (AActor *thing);
void P_FakeZMovement (AActor *mo); 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); bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false);

View file

@ -2828,7 +2828,7 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t
} }
// set openrange, opentop, openbottom // 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) if (open.range < slidemo->Height)
goto isblocking; // doesn't fit 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) if (open.range < slidemo->Height)
goto bounceblocking; // doesn't fit goto bounceblocking; // doesn't fit
@ -3806,7 +3806,7 @@ struct aim_t
// Crosses a two sided line. // Crosses a two sided line.
// A two sided line will restrict the possible target ranges. // A two sided line will restrict the possible target ranges.
FLineOpening open; 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. // The following code assumes that portals on the front of the line have already been processed.
@ -3831,7 +3831,7 @@ struct aim_t
return; return;
int planestocheck; int planestocheck;
if (!AimTraverse3DFloors(it.Trace(), in, frontflag, &planestocheck)) if (!AimTraverse3DFloors(it._f_Trace(), in, frontflag, &planestocheck))
return; return;
if (aimdebug) if (aimdebug)
@ -3961,7 +3961,7 @@ struct aim_t
fixed_t cosine = finecosine[thingpitch >> ANGLETOFINESHIFT]; fixed_t cosine = finecosine[thingpitch >> ANGLETOFINESHIFT];
if (cosine != 0) 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) if (d3 > attackrange)
{ {
return; 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) void P_TraceBleed(int damage, AActor *target, AActor *missile)
{ {
int pitch; DAngle pitch;
if (target == NULL || missile->flags3 & MF3_BLOODLESSIMPACT) if (target == NULL || missile->flags3 & MF3_BLOODLESSIMPACT)
{ {
@ -4572,15 +4572,13 @@ void P_TraceBleed(int damage, AActor *target, AActor *missile)
double aim; double aim;
aim = g_atan((double)missile->_f_velz() / (double)target->AproxDistance(missile)); aim = g_atan((double)missile->_f_velz() / (double)target->AproxDistance(missile));
pitch = -(int)(aim * ANGLE_180 / PI); pitch = -ToDegrees(aim);
} }
else else
{ {
pitch = 0; pitch = 0.;
} }
P_TraceBleed(damage, target->_f_X(), target->_f_Y(), target->_f_Z() + target->_f_height() / 2, P_TraceBleed(damage, target->PosPlusZ(target->Height/2), target, missile->AngleTo(target), pitch);
target, missile->__f_AngleTo(target),
pitch);
} }
//========================================================================== //==========================================================================
@ -4958,7 +4956,7 @@ bool P_UseTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t end
} }
else 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 || if (open.range <= 0 ||
(in->d.line->special != 0 && (i_compatflags & COMPATF_USEBLOCKING))) (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->special) continue;
if (ld->isLinePortal()) return false; if (ld->isLinePortal()) return false;
if (ld->flags&(ML_BLOCKING | ML_BLOCKEVERYTHING | ML_BLOCK_PLAYERS)) return true; 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 || if (open.range <= 0 ||
open.bottom > usething->Z() + usething->MaxStepHeight || open.bottom > usething->Z() + usething->MaxStepHeight ||
open.top < usething->Top()) return true; open.top < usething->Top()) return true;
@ -5148,7 +5146,7 @@ bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType)
{ // Check line { // Check line
if (in->d.line->special != UsePuzzleItem) 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) if (open.range <= 0)
{ {
return false; // can't use through a wall return false; // can't use through a wall

View file

@ -1425,6 +1425,7 @@ intercept_t *FPathTraverse::Next()
{ {
dist = scan->frac; dist = scan->frac;
in = scan; 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; break;
} }
} }
ftrace.dx = FIXED2DBL(trace.dx);
ftrace.dy = FIXED2DBL(trace.dy);
ftrace.x = FIXED2DBL(trace.x);
ftrace.y = FIXED2DBL(trace.y);
} }
//=========================================================================== //===========================================================================

View file

@ -25,6 +25,7 @@ struct divline_t
struct intercept_t struct intercept_t
{ {
double Frac;
fixed_t frac; // along trace line fixed_t frac; // along trace line
bool isaline; bool isaline;
bool done; bool done;
@ -390,6 +391,7 @@ class FPathTraverse
protected: protected:
static TArray<intercept_t> intercepts; static TArray<intercept_t> intercepts;
divline_t ftrace;
fdivline_t trace; fdivline_t trace;
fixed_t startfrac; fixed_t startfrac;
unsigned int intercept_index; unsigned int intercept_index;
@ -407,12 +409,17 @@ public:
{ {
init(x1, y1, x2, y2, flags, startfrac); 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); 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); int PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos = NULL);
virtual ~FPathTraverse(); 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 return
{ {
@ -420,6 +427,14 @@ public:
trace.y + FixedMul(trace.dy, in->frac) 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))
};
}
}; };

View file

@ -3171,9 +3171,8 @@ bool AActor::IsOkayToAttack (AActor *link)
// to only allow the check to succeed if the enemy was in a ~84<38> FOV of the player // to only allow the check to succeed if the enemy was in a ~84<38> FOV of the player
if (flags3 & MF3_SCREENSEEKER) if (flags3 & MF3_SCREENSEEKER)
{ {
angle_t angle = Friend->__f_AngleTo(link) - Friend->_f_angle(); DAngle angle = absangle(Friend->AngleTo(link), Friend->Angles.Yaw);
angle >>= 24; if (angle < 30 * (256./360.))
if (angle>226 || angle<30)
{ {
return true; return true;
} }
@ -3562,7 +3561,7 @@ void AActor::Tick ()
{ {
if (!players[i].Bot->missile && (flags3 & MF3_WARNBOT)) if (!players[i].Bot->missile && (flags3 & MF3_WARNBOT))
{ //warn for incoming missiles. { //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; players[i].Bot->missile = this;
} }
} }

View file

@ -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); 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 (arc.IsLoading ())
{ {
// If the player reloaded because they pressed +use after dying, we // If the player reloaded because they pressed +use after dying, we

View file

@ -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. // Teleport portals are intentionally ignored since skipping this stuff is their entire reason for existence.
if (port->mFlags & PORTF_INTERACTIVE) if (port->mFlags & PORTF_INTERACTIVE)
{ {
fixedvec2 hit = it.InterceptPoint(in); fixedvec2 hit = it._f_InterceptPoint(in);
if (port->mType == PORTT_LINKED) if (port->mType == PORTT_LINKED)
{ {